From 4985bfcc6ded90054a8f3bc9ed76d30f58683cf1 Mon Sep 17 00:00:00 2001 From: liushuyu Date: Wed, 31 May 2023 22:08:02 -0600 Subject: [PATCH] gccrs: rust-builtins: add likely and unlikey intrinsics gcc/rust/ChangeLog: * backend/rust-builtins.cc: add `expect` builtin definition. * backend/rust-compile-intrinsic.cc: add `likely` and `unlikely` intrinsics handler. Signed-off-by: Zixing Liu --- gcc/rust/backend/rust-builtins.cc | 6 +++ gcc/rust/backend/rust-compile-intrinsic.cc | 57 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc index c96553b8c595..cd06379fcb00 100644 --- a/gcc/rust/backend/rust-builtins.cc +++ b/gcc/rust/backend/rust-builtins.cc @@ -242,6 +242,12 @@ BuiltinsContext::setup () build_function_type (void_type_node, void_list_node), builtin_const | builtin_noreturn); + define_builtin ("expect", BUILT_IN_EXPECT, "__builtin_expect", "expect", + build_function_type_list (long_integer_type_node, + long_integer_type_node, + long_integer_type_node, NULL_TREE), + builtin_const); + define_builtin ("memcpy", BUILT_IN_MEMCPY, "__builtin_memcpy", "memcpy", build_function_type_list (build_pointer_type (void_type_node), build_pointer_type (void_type_node), diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 243aab7dcb40..33ec9128cc93 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -165,6 +165,17 @@ unchecked_op_handler (tree_code op) }; } +static inline tree +expect_handler_inner (Context *ctx, TyTy::FnType *fntype, bool likely); + +const static std::function +expect_handler (bool likely) +{ + return [likely] (Context *ctx, TyTy::FnType *fntype) { + return expect_handler_inner (ctx, fntype, likely); + }; +} + inline tree sorry_handler (Context *ctx, TyTy::FnType *fntype) { @@ -208,6 +219,8 @@ static const std::mapget_params ().size () == 1); + + tree lookup = NULL_TREE; + if (check_for_cached_intrinsic (ctx, fntype, &lookup)) + return lookup; + + auto fndecl = compile_intrinsic_function (ctx, fntype); + + enter_intrinsic_block (ctx, fndecl); + + // BUILTIN expect_handler_inner FN BODY BEGIN + // setup the params + std::vector param_vars; + compile_fn_params (ctx, fntype, fndecl, ¶m_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); + rust_assert (expect_fn_raw); + auto expect_fn = build_fold_addr_expr_loc (BUILTINS_LOCATION, expect_fn_raw); + + // we need to convert the expression return type to long to match the expected + // parameter type of __builtin_expect + auto expect_src = build1 (CONVERT_EXPR, long_integer_type_node, expr); + auto expect_value + = make_unsigned_long_tree (static_cast (likely)); + + auto expect_call + = Backend::call_expression (expect_fn, {expect_src, expect_value}, nullptr, + BUILTINS_LOCATION); + // the return value also needs to be casted (to bool) + auto expect_call_bool = build1 (CONVERT_EXPR, boolean_type_node, expect_call); + auto return_statement + = Backend::return_statement (fndecl, expect_call_bool, BUILTINS_LOCATION); + ctx->add_statement (return_statement); + // BUILTIN expect_handler_inner FN BODY END + + finalize_intrinsic_block (ctx, fndecl); + + return fndecl; +} + } // namespace Compile } // namespace Rust -- 2.47.2