aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorliushuyu <liushuyu011@gmail.com>2023-05-31 22:08:02 -0600
committerArthur Cohen <arthur.cohen@embecosm.com>2024-01-16 19:04:36 +0100
commit4985bfcc6ded90054a8f3bc9ed76d30f58683cf1 (patch)
tree38439431e7b48c6271cf5c97b81b4a64e186d21f /gcc
parentb1b42beea3d16d9b129ee53d173a299c5c8d33e2 (diff)
downloadgcc-4985bfcc6ded90054a8f3bc9ed76d30f58683cf1.zip
gcc-4985bfcc6ded90054a8f3bc9ed76d30f58683cf1.tar.gz
gcc-4985bfcc6ded90054a8f3bc9ed76d30f58683cf1.tar.bz2
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 <liushuyu011@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-builtins.cc6
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc57
2 files changed, 63 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index c96553b..cd06379 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 243aab7..33ec912 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<tree (Context *, TyTy::FnType *)>
+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::map<std::string,
{"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)},
{"uninit", uninit_handler},
{"move_val_init", move_val_init_handler},
+ {"likely", expect_handler (true)},
+ {"unlikely", expect_handler (false)},
};
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -1104,5 +1117,49 @@ move_val_init_handler (Context *ctx, TyTy::FnType *fntype)
return fndecl;
}
+static inline tree
+expect_handler_inner (Context *ctx, TyTy::FnType *fntype, bool likely)
+{
+ rust_assert (fntype->get_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<Bvariable *> param_vars;
+ 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);
+ 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<unsigned long> (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