Skip to content

Commit

Permalink
Remove 3 casts and replace them with a single new normal expression n…
Browse files Browse the repository at this point in the history
…ode.
  • Loading branch information
lerno committed Dec 29, 2024
1 parent 7b734df commit 5af224a
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 158 deletions.
2 changes: 2 additions & 0 deletions src/compiler/c_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr)
{
switch (expr->expr_kind)
{
case EXPR_EXT_TRUNC:
break;
case EXPR_ACCESS:
break;
case EXPR_ANYSWITCH:
Expand Down
24 changes: 21 additions & 3 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,12 @@ typedef struct
SemaContext *context;
} ExprOtherContext;

typedef struct
{
Expr *inner;
bool is_signed;
} ExprExtTrunc;

struct Expr_
{
Type *type;
Expand All @@ -1142,15 +1148,16 @@ struct Expr_
ExprCtCall ct_call_expr; // 24
ExprIdentifierRaw ct_ident_expr; // 24
Decl *decl_expr; // 8
Expr** designated_init_list; // 8
Expr **designated_init_list; // 8
ExprDesignator designator_expr; // 16
ExprNamedArgument named_argument_expr;
ExprEmbedExpr embed_expr; // 16
Expr** exec_expr; // 8
Expr **exec_expr; // 8
ExprAsmArg expr_asm_arg; // 24
ExprFuncBlock expr_block; // 4
ExprCompoundLiteral expr_compound_literal; // 16
Expr** expression_list; // 8
Expr **expression_list; // 8
ExprExtTrunc ext_trunc_expr;
ExprGenericIdent generic_ident_expr;
ExprDefaultArg default_arg_expr;
ExprIdentifierRaw hash_ident_expr; // 24
Expand Down Expand Up @@ -3273,6 +3280,9 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc)
expr->span = loc;
switch (expr->expr_kind)
{
case EXPR_EXT_TRUNC:
expr_set_span(expr->ext_trunc_expr.inner, loc);
return;
case EXPR_NAMED_ARGUMENT:
expr->named_argument_expr.name_span = loc;
expr_set_span(expr->named_argument_expr.value, loc);
Expand Down Expand Up @@ -3581,6 +3591,14 @@ INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type)
expr->resolve_status = RESOLVE_DONE;
}

INLINE void expr_rewrite_ext_trunc(Expr *expr, Type *type, bool is_signed)
{
Expr *inner = expr_copy(expr);
expr->expr_kind = EXPR_EXT_TRUNC;
expr->ext_trunc_expr = (ExprExtTrunc) { .inner = inner, .is_signed = is_signed };
expr->type = type;
}

INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v)
{
expr->expr_kind = EXPR_CONST;
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/copying.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
case EXPR_SWIZZLE:
MACRO_COPY_EXPRID(expr->swizzle_expr.parent);
return expr;
case EXPR_EXT_TRUNC:
MACRO_COPY_EXPR(expr->ext_trunc_expr.inner);
return expr;
case EXPR_NOP:
case EXPR_BUILTIN:
case EXPR_RETVAL:
Expand Down
5 changes: 1 addition & 4 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,10 @@ typedef enum
CAST_ARRVEC,
CAST_BOOLBOOL,
CAST_BOOLFP,
CAST_BOOLINT,
CAST_BOOLVECINT,
CAST_BSINTARR,
CAST_BSBOOL,
CAST_INTARRBS,
CAST_EREU,
CAST_ERINT,
CAST_ERPTR,
CAST_ERROR,
CAST_EUBOOL,
Expand All @@ -560,7 +557,6 @@ typedef enum
CAST_INTFP,
CAST_IDPTR,
CAST_IDBOOL,
CAST_IDINT,
CAST_PTRANY,
CAST_PTRBOOL,
CAST_PTRPTR,
Expand Down Expand Up @@ -823,6 +819,7 @@ typedef enum
EXPR_TYPEINFO,
EXPR_UNARY,
EXPR_VASPLAT,
EXPR_EXT_TRUNC,
EXPR_LAST = EXPR_VASPLAT
} ExprKind;

Expand Down
9 changes: 5 additions & 4 deletions src/compiler/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ bool expr_may_addr(Expr *expr)
case EXPR_TYPEID:
case EXPR_TYPEID_INFO:
case EXPR_VASPLAT:
case EXPR_EXT_TRUNC:
return false;
}
UNREACHABLE
Expand Down Expand Up @@ -204,6 +205,8 @@ bool expr_is_runtime_const(Expr *expr)
return exprid_is_runtime_const(expr->builtin_access_expr.inner);
case EXPR_CAST:
return expr_cast_is_runtime_const(expr);
case EXPR_EXT_TRUNC:
return expr_is_runtime_const(expr->ext_trunc_expr.inner);
case EXPR_CONST:
return true;
case EXPR_DESIGNATOR:
Expand Down Expand Up @@ -338,7 +341,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
case CAST_EREU:
case CAST_STRPTR:
case CAST_PTRBOOL:
case CAST_BOOLINT:
case CAST_BOOLFP:
case CAST_BOOLBOOL:
case CAST_FPBOOL:
Expand All @@ -350,7 +352,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
case CAST_STINLINE:
case CAST_VECARR:
case CAST_ARRVEC:
case CAST_BOOLVECINT:
case CAST_INTINT:
return exprid_is_runtime_const(expr->cast_expr.expr);
case CAST_INTPTR:
Expand All @@ -367,9 +368,7 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
return exprid_is_runtime_const(expr->cast_expr.expr);
case CAST_PTRANY:
return exprid_is_runtime_const(expr->cast_expr.expr);
case CAST_ERINT:
case CAST_PTRINT:
case CAST_IDINT:
case CAST_INTARRBS:
case CAST_BSINTARR:
case CAST_BSBOOL:
Expand Down Expand Up @@ -605,6 +604,8 @@ bool expr_is_pure(Expr *expr)
case EXPR_BENCHMARK_HOOK:
case EXPR_TEST_HOOK:
return false;
case EXPR_EXT_TRUNC:
return expr_is_pure(expr->ext_trunc_expr.inner);
case EXPR_OTHER_CONTEXT:
return expr_is_pure(expr->expr_other_context.inner);
case EXPR_SWIZZLE:
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/json_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ void print_var_expr(FILE *file, Expr *expr)
fputs(".", file);
print_var_expr(file, expr->access_expr.child);
break;
case EXPR_EXT_TRUNC:
TODO
case EXPR_BINARY:
print_var_expr(file, exprptr(expr->binary_expr.left));
switch (expr->binary_expr.operator)
Expand Down
47 changes: 15 additions & 32 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1319,13 +1319,6 @@ void llvm_emit_expand_to_vec_cast(GenContext *c, BEValue *value, Type *to_type,
llvm_value_set(value, res, to_type);
}

static void llvm_emit_bool_to_intvec_cast(GenContext *c, BEValue *value, Type *to_type, Type *from_type)
{
llvm_value_rvalue(c, value);
LLVMTypeRef type = llvm_get_type(c, to_type);
LLVMValueRef res = LLVMBuildSExt(c->builder, value->value, type, "");
llvm_value_set(value, res, to_type);
}

// Prune the common occurrence where the optional is not used.
static void llvm_prune_optional(GenContext *c, LLVMBasicBlockRef discard_fail)
Expand Down Expand Up @@ -1456,9 +1449,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_BOOLVECINT:
llvm_emit_bool_to_intvec_cast(c, value, to_type, from_type);
return;
case CAST_ARRVEC:
llvm_emit_array_to_vector_cast(c, value, to_type, from_type);
return;
Expand All @@ -1472,23 +1462,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
}
case CAST_VOID:
UNREACHABLE;
case CAST_ERINT:
case CAST_IDINT:
to_type = type_lowering(to_type);
from_type = type_lowering(from_type);
llvm_value_rvalue(c, value);
if (type_convert_will_trunc(to_type, from_type))
{
value->value = LLVMBuildTrunc(c->builder, value->value, llvm_get_type(c, to_type), "errinttrunc");
}
else
{
value->value = type_is_signed(to_type)
? LLVMBuildSExt(c->builder, value->value, llvm_get_type(c, to_type), "errsiext")
: LLVMBuildZExt(c->builder, value->value, llvm_get_type(c, to_type), "erruiext");

}
break;
case CAST_ANYBOOL:
llvm_emit_any_pointer(c, value, value);
llvm_value_rvalue(c, value);
Expand Down Expand Up @@ -1541,11 +1514,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
case CAST_BSINTARR:
case CAST_INTARRBS:
break;
case CAST_BOOLINT:
llvm_value_rvalue(c, value);
value->value = LLVMBuildZExt(c->builder, value->value, llvm_get_type(c, to_type), "boolsi");
value->kind = BE_VALUE;
break;
case CAST_FPBOOL:
llvm_value_rvalue(c, value);
value->value = LLVMBuildFCmp(c->builder, LLVMRealUNE, value->value, llvm_get_zero(c, from_type), "fpbool");
Expand Down Expand Up @@ -7231,6 +7199,18 @@ void llvm_emit_expr_global_value(GenContext *c, BEValue *value, Expr *expr)
llvm_emit_expr(c, value, expr);
ASSERT0(!llvm_value_is_addr(value));
}

static void llvm_emit_ext_trunc(GenContext *c, BEValue *value, Expr *expr)
{
llvm_emit_expr(c, value, expr->ext_trunc_expr.inner);
llvm_value_rvalue(c, value);
Type *to_type = type_lowering(expr->type);
LLVMTypeRef to = llvm_get_type(c, to_type);
llvm_value_set(value, expr->ext_trunc_expr.is_signed
? llvm_sext_trunc(c, value->value, to)
: llvm_zext_trunc(c, value->value, to), to_type);
}

void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
{
EMIT_EXPR_LOC(c, expr);
Expand All @@ -7249,6 +7229,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_MEMBER_GET:
case EXPR_NAMED_ARGUMENT:
UNREACHABLE
case EXPR_EXT_TRUNC:
llvm_emit_ext_trunc(c, value, expr);
return;
case EXPR_DEFAULT_ARG:
llvm_emit_default_arg(c, value, expr);
return;
Expand Down
19 changes: 15 additions & 4 deletions src/compiler/sema_casts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1467,9 +1467,16 @@ static void cast_vaptr_to_slice(SemaContext *context, Expr *expr, Type *type) {
static void cast_ptr_to_any(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_PTRANY, type); }
static void cast_struct_to_inline(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_STINLINE, type); }
static void cast_fault_to_anyfault(SemaContext *context, Expr *expr, Type *type) { expr->type = type; };
static void cast_fault_to_int(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ERINT, type); }
static void cast_fault_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ERPTR, type); }
static void cast_typeid_to_int(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_IDINT, type); }
static void cast_typeid_to_int(SemaContext *context, Expr *expr, Type *type)
{
expr_rewrite_ext_trunc(expr, type, type_is_signed(type_flatten(type)));
}

static void cast_fault_to_int(SemaContext *context, Expr *expr, Type *type)
{
return cast_typeid_to_int(context, expr, type);
}
static void cast_typeid_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_IDPTR, type); }
static void cast_any_to_bool(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ANYBOOL, type); }
static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ANYPTR, type); }
Expand Down Expand Up @@ -1810,7 +1817,7 @@ static void cast_vec_to_vec(SemaContext *context, Expr *expr, Type *to_type)
// Special conversion to retain the sign.
if (type_is_integer(to_element))
{
insert_runtime_cast(expr, CAST_BOOLVECINT, to_type);
expr_rewrite_ext_trunc(expr, to_type, true);
return;
}
if (type_is_float(to_element))
Expand Down Expand Up @@ -1934,7 +1941,11 @@ static void cast_int_to_ptr(SemaContext *context, Expr *expr, Type *type)
*/
static void cast_bool_to_int(SemaContext *context, Expr *expr, Type *type)
{
if (insert_runtime_cast_unless_const(expr, CAST_BOOLINT, type)) return;
if (!sema_cast_const(expr))
{
expr_rewrite_ext_trunc(expr, type, false);
return;
}

expr_rewrite_const_int(expr, type, expr->const_expr.b ? 1 : 0);
}
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
RETURN_SEMA_ERROR(expr, "This expression is a value and cannot be assigned to.");
case EXPR_CT_IDENT:
return true;
case EXPR_EXT_TRUNC:
return false;
case EXPR_OTHER_CONTEXT:
return sema_binary_is_expr_lvalue(context, top_expr, expr->expr_other_context.inner);
case EXPR_IDENTIFIER:
Expand Down Expand Up @@ -593,6 +595,7 @@ static bool expr_may_ref(Expr *expr)
case EXPR_DEFAULT_ARG:
case EXPR_TYPECALL:
case EXPR_MEMBER_GET:
case EXPR_EXT_TRUNC:
return false;
case EXPR_OTHER_CONTEXT:
return expr_may_ref(expr->expr_other_context.inner);
Expand Down Expand Up @@ -8925,6 +8928,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
case EXPR_TYPECALL:
case EXPR_MEMBER_GET:
case EXPR_SPLAT:
case EXPR_EXT_TRUNC:
if (!sema_analyse_expr(active_context, main_expr)) return false;
break;
}
Expand Down Expand Up @@ -9302,6 +9306,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
case EXPR_TRY_UNWRAP_CHAIN:
case EXPR_TYPEID_INFO:
UNREACHABLE
case EXPR_EXT_TRUNC:
return sema_analyse_expr(context, expr->ext_trunc_expr.inner);
case EXPR_SPLAT:
RETURN_SEMA_ERROR(expr, "Splat ('...') may only appear in initializers and calls.");
case EXPR_TYPECALL:
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 @@ -485,6 +485,9 @@ static void sema_trace_expr_liveness(Expr *expr)
case EXPR_TRY_UNWRAP_CHAIN:
sema_trace_expr_list_liveness(expr->try_unwrap_chain_expr);
return;
case EXPR_EXT_TRUNC:
sema_trace_expr_liveness(expr->ext_trunc_expr.inner);
return;
case EXPR_TYPEID:
case EXPR_LAST_FAULT:
return;
Expand Down
1 change: 1 addition & 0 deletions src/compiler/sema_stmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
case EXPR_ACCESS:
case EXPR_ASM:
case EXPR_DEFAULT_ARG:
case EXPR_EXT_TRUNC:
return true;
}
UNREACHABLE
Expand Down
14 changes: 7 additions & 7 deletions test/test_suite/bitstruct/array_with_boolean.c3t
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ entry:
%7 = load i8, ptr %ptradd14, align 1
%lshrl15 = lshr i8 %7, 3
%8 = trunc i8 %lshrl15 to i1
%boolsi = zext i1 %8 to i32
%ptradd16 = getelementptr inbounds i8, ptr %xx, i64 2
%9 = load i8, ptr %ptradd16, align 1
%lshrl17 = lshr i8 %9, 4
%10 = trunc i8 %lshrl17 to i1
%boolsi18 = zext i1 %10 to i32
call void (ptr, ...) @printf(ptr @.str, i32 %ashr, i32 %ashr5, i32 %ashr13, i32 %boolsi, i32 %boolsi18)
%zext16 = zext i1 %8 to i32
%ptradd17 = getelementptr inbounds i8, ptr %xx, i64 2
%9 = load i8, ptr %ptradd17, align 1
%lshrl18 = lshr i8 %9, 4
%10 = trunc i8 %lshrl18 to i1
%zext19 = zext i1 %10 to i32
call void (ptr, ...) @printf(ptr @.str, i32 %ashr, i32 %ashr5, i32 %ashr13, i32 %zext16, i32 %zext19)
ret void
}
Loading

0 comments on commit 5af224a

Please sign in to comment.