Skip to content

Commit

Permalink
Fixup builtin refactor from Arthur
Browse files Browse the repository at this point in the history
Add attributes support through LANG_HOOKS_COMMON_ATTRIBUTE_TABLE lang hook.
Based on D frontend.

gcc/rust/ChangeLog:

	* Make-lang.in (GRS_OBJS): Add rust-attribs.o.
	* backend/rust-builtins.cc
	(BuiltinsContext::define_function_type): Set builtin type to
	errormark so the builtin is considered unavailable.
	(BuiltinsContext::register_rust_mappings): Add all missing
	builtins.
	(builtin_const, builtin_noreturn, builtin_novops): Remove.
	* backend/rust-compile-intrinsic.cc (Intrinsics::compile): Add comment.
	(op_with_overflow_inner): Fix builtin name.
	(prefetch_data_handler): Adjust call.
	(uninit_handler): Likewise.
	(move_val_init_handler): Likewise.
	(expect_handler_inner): Likewise.
	* rust-lang.cc (grs_langhook_common_attribute_table): New.
	(LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Define.
	* rust-attribs.cc: New file.

gcc/testsuite/ChangeLog:

	* rust/compile/torture/builtin_abort.rs: New test.
	* rust/execute/torture/builtin_abort.rs: New test.

Signed-off-by: Marc Poulhiès <dkm@kataplop.net>
  • Loading branch information
dkm committed Nov 11, 2023
1 parent 899eb62 commit 4907f4d
Show file tree
Hide file tree
Showing 9 changed files with 512 additions and 82 deletions.
1 change: 1 addition & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
# The compiler proper, not driver
GRS_OBJS = \
rust/rust-lang.o \
rust/rust-attribs.o \
rust/rust-object-export.o \
rust/rust-linemap.o \
rust/rust-diagnostics.o \
Expand Down
44 changes: 40 additions & 4 deletions gcc/rust/backend/rust-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
namespace Rust {
namespace Compile {

static const int builtin_const = 1 << 0;
static const int builtin_noreturn = 1 << 1;
static const int builtin_novops = 1 << 2;

BuiltinsContext &
BuiltinsContext::get ()
{
Expand Down Expand Up @@ -74,6 +70,8 @@ BuiltinsContext::define_function_type (Type def_idx, Type ret_idx,
auto return_type = builtin_types[ret_idx];
if (return_type == error_mark_node)
{
// Mark the builtin as not available.
builtin_types[def_idx] = error_mark_node;
va_end (list);
return;
}
Expand Down Expand Up @@ -287,8 +285,46 @@ BuiltinsContext::register_rust_mappings ()
rust_intrinsic_to_gcc_builtin = {
{"sinf32", "__builtin_sinf"},
{"sqrtf32", "__builtin_sqrtf"},
{"sqrtf64", "__builtin_sqrt"},
{"unreachable", "__builtin_unreachable"},
{"abort", "__builtin_abort"},
{"sinf64", "__builtin_sin"},
{"cosf32", "__builtin_cosf"},
{"cosf64", "__builtin_cos"},
{"powf32", "__builtin_powf"},
{"powf64", "__builtin_pow"},
{"expf32", "__builtin_expf"},
{"expf64", "__builtin_exp"},
{"exp2f32", "__builtin_exp2f"},
{"exp2f64", "__builtin_exp2"},
{"logf32", "__builtin_logf"},
{"logf64", "__builtin_log"},
{"log10f32", "__builtin_log10f"},
{"log10f64", "__builtin_log10"},
{"log2f32", "__builtin_log2f"},
{"log2f64", "__builtin_log2"},
{"fmaf32", "__builtin_fmaf"},
{"fmaf64", "__builtin_fma"},
{"fabsf32", "__builtin_fabsf"},
{"fabsf64", "__builtin_fabs"},
{"minnumf32", "__builtin_fminf"},
{"minnumf64", "__builtin_fmin"},
{"maxnumf32", "__builtin_fmaxf"},
{"maxnumf64", "__builtin_fmax"},
{"copysignf32", "__builtin_copysignf"},
{"copysignf64", "__builtin_copysign"},
{"floorf32", "__builtin_floorf"},
{"floorf64", "__builtin_floor"},
{"ceilf32", "__builtin_ceilf"},
{"ceilf64", "__builtin_ceil"},
{"truncf32", "__builtin_truncf"},
{"truncf64", "__builtin_trunc"},
{"rintf32", "__builtin_rintf"},
{"rintf64", "__builtin_rint"},
{"nearbyintf32", "__builtin_nearbyintf"},
{"nearbyintf64", "__builtin_nearbyint"},
{"roundf32", "__builtin_roundf"},
{"roundf64", "__builtin_round"},
};
}

Expand Down
43 changes: 27 additions & 16 deletions gcc/rust/backend/rust-compile-intrinsic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ static const std::map<std::string,

Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}

/**
* Returns a FUNC_DECL corresponding to the intrinsic function FNTYPE. If a
* corresponding builtin exists, returns it. If not, search in the generic
* intrinsics declared and delegate the return to the corresponding handler.
*
* @param fntype The Rust function type that should be implemented by the
* compiler
*/
tree
Intrinsics::compile (TyTy::FnType *fntype)
{
Expand Down Expand Up @@ -656,17 +664,17 @@ op_with_overflow_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
switch (op)
{
case PLUS_EXPR:
BuiltinsContext::get ().lookup_simple_builtin ("add_overflow",
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_add_overflow",
&overflow_builtin);
break;

case MINUS_EXPR:
BuiltinsContext::get ().lookup_simple_builtin ("sub_overflow",
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_sub_overflow",
&overflow_builtin);
break;

case MULT_EXPR:
BuiltinsContext::get ().lookup_simple_builtin ("mul_overflow",
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_mul_overflow",
&overflow_builtin);
break;

Expand Down Expand Up @@ -752,7 +760,8 @@ copy_handler_inner (Context *ctx, TyTy::FnType *fntype, bool overlaps)
= build2 (MULT_EXPR, size_type_node, TYPE_SIZE_UNIT (param_type), count);

tree memcpy_raw = nullptr;
BuiltinsContext::get ().lookup_simple_builtin (overlaps ? "__builtin_memmove" : "__builtin_memcpy",
BuiltinsContext::get ().lookup_simple_builtin (overlaps ? "__builtin_memmove"
: "__builtin_memcpy",
&memcpy_raw);
rust_assert (memcpy_raw);
auto memcpy = build_fold_addr_expr_loc (UNKNOWN_LOCATION, memcpy_raw);
Expand Down Expand Up @@ -798,7 +807,7 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)

enter_intrinsic_block (ctx, fndecl);

auto addr = ctx->get_backend ()->var_expression (args[0], Location ());
auto addr = Backend::var_expression (args[0], UNDEF_LOCATION);

// The core library technically allows you to pass any i32 value as a
// locality, but LLVM will then complain if the value cannot be constant
Expand All @@ -812,22 +821,21 @@ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
// site directly This has the bad side-effect of creating warnings about
// `unused name - locality`, which we hack away here:
// TODO: Take care of handling locality properly
ctx->get_backend ()->var_expression (args[1], Location ());
Backend::var_expression (args[1], UNDEF_LOCATION);

auto rw_flag = make_unsigned_long_tree (ctx, kind == Prefetch::Write ? 1 : 0);
auto rw_flag = make_unsigned_long_tree (kind == Prefetch::Write ? 1 : 0);

auto prefetch_raw = NULL_TREE;
auto ok = BuiltinsContext::get ().lookup_simple_builtin ("__builtin_prefetch",
&prefetch_raw);
rust_assert (ok);
auto prefetch = build_fold_addr_expr_loc (UNKNOWN_LOCATION, prefetch_raw);

auto prefetch_call
= ctx->get_backend ()->call_expression (prefetch,
{addr, rw_flag,
// locality arg
make_unsigned_long_tree (ctx, 3)},
nullptr, Location ());
auto prefetch_call = Backend::call_expression (prefetch,
{addr, rw_flag,
// locality arg
make_unsigned_long_tree (3)},
nullptr, UNDEF_LOCATION);

TREE_READONLY (prefetch_call) = 0;
TREE_SIDE_EFFECTS (prefetch_call) = 1;
Expand Down Expand Up @@ -1087,7 +1095,8 @@ uninit_handler (Context *ctx, TyTy::FnType *fntype)
// BUILTIN size_of FN BODY BEGIN

tree memset_builtin = error_mark_node;
BuiltinsContext::get ().lookup_simple_builtin ("memset", &memset_builtin);
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_memset",
&memset_builtin);
rust_assert (memset_builtin != error_mark_node);

// call memset with 0x01 and size of the thing see
Expand Down Expand Up @@ -1150,7 +1159,8 @@ move_val_init_handler (Context *ctx, TyTy::FnType *fntype)
tree size = TYPE_SIZE_UNIT (template_parameter_type);

tree memcpy_builtin = error_mark_node;
BuiltinsContext::get ().lookup_simple_builtin ("memcpy", &memcpy_builtin);
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_memcpy",
&memcpy_builtin);
rust_assert (memcpy_builtin != error_mark_node);

src = build_fold_addr_expr_loc (BUILTINS_LOCATION, src);
Expand Down Expand Up @@ -1184,7 +1194,8 @@ expect_handler_inner (Context *ctx, TyTy::FnType *fntype, bool likely)
compile_fn_params (ctx, fntype, fndecl, &param_vars);
tree expr = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
tree expect_fn_raw = nullptr;
BuiltinsContext::get ().lookup_simple_builtin ("expect", &expect_fn_raw);
BuiltinsContext::get ().lookup_simple_builtin ("__builtin_expect",
&expect_fn_raw);
rust_assert (expect_fn_raw);
auto expect_fn = build_fold_addr_expr_loc (BUILTINS_LOCATION, expect_fn_raw);

Expand Down
Loading

0 comments on commit 4907f4d

Please sign in to comment.