diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-10-07 08:00:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-07 08:00:32 +0000 |
commit | e623ee314fbc9503067bbb379a4055dd4d5d245b (patch) | |
tree | 98c59bdbe77ea1c6c349da2b15e945454b3fdd67 /gcc/rust | |
parent | b4096017e3b9ca499b56988b67e05667a02ca202 (diff) | |
parent | 71397abfbe573beee3415e7031bcea84d80cdd6e (diff) | |
download | gcc-e623ee314fbc9503067bbb379a4055dd4d5d245b.zip gcc-e623ee314fbc9503067bbb379a4055dd4d5d245b.tar.gz gcc-e623ee314fbc9503067bbb379a4055dd4d5d245b.tar.bz2 |
Merge #1565
1565: Implement data prefetch intrinsics r=CohenArthur a=CohenArthur
Addresses #658
Needs #1564 so only review the last commit
This PR implements the two intrinsics related to data prefetching. I have to say, since these are hints for the backend, I am unsure if the current implementation is right. I believe it should be.
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/backend/rust-builtins.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-intrinsic.cc | 97 |
2 files changed, 94 insertions, 9 deletions
diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc index 14dc037..d6f8cb6 100644 --- a/gcc/rust/backend/rust-builtins.cc +++ b/gcc/rust/backend/rust-builtins.cc @@ -92,6 +92,12 @@ BuiltinsContext::setup () build_pointer_type (void_type_node), size_type_node, NULL_TREE), 0); + + define_builtin ("prefetch", BUILT_IN_PREFETCH, "__builtin_prefetch", + "prefetch", + build_varargs_function_type_list ( + build_pointer_type (const_ptr_type_node), NULL_TREE), + builtin_const); } static void diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 6169196..a418b86 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -17,6 +17,7 @@ #include "rust-compile-intrinsic.h" #include "rust-compile-context.h" #include "rust-compile-type.h" +#include "rust-compile-expr.h" #include "rust-compile-fnparam.h" #include "rust-builtins.h" #include "rust-diagnostics.h" @@ -28,6 +29,8 @@ #include "fold-const.h" #include "langhooks.h" +#include "print-tree.h" + namespace Rust { namespace Compile { @@ -44,6 +47,15 @@ wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op); static tree copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype); +enum class Prefetch +{ + Read, + Write +}; + +static tree +prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind); + static inline tree rotate_left_handler (Context *ctx, TyTy::FnType *fntype) { @@ -70,18 +82,32 @@ wrapping_mul_handler (Context *ctx, TyTy::FnType *fntype) { return wrapping_op_handler (ctx, fntype, MULT_EXPR); } +static inline tree +prefetch_read_data (Context *ctx, TyTy::FnType *fntype) +{ + return prefetch_data_handler (ctx, fntype, Prefetch::Read); +} +static inline tree +prefetch_write_data (Context *ctx, TyTy::FnType *fntype) +{ + return prefetch_data_handler (ctx, fntype, Prefetch::Write); +} static const std::map<std::string, std::function<tree (Context *, TyTy::FnType *)>> - generic_intrinsics = {{"offset", &offset_handler}, - {"size_of", &sizeof_handler}, - {"transmute", &transmute_handler}, - {"rotate_left", &rotate_left_handler}, - {"rotate_right", &rotate_right_handler}, - {"wrapping_add", &wrapping_add_handler}, - {"wrapping_sub", &wrapping_sub_handler}, - {"wrapping_mul", &wrapping_mul_handler}, - {"copy_nonoverlapping", ©_nonoverlapping_handler}}; + generic_intrinsics = { + {"offset", &offset_handler}, + {"size_of", &sizeof_handler}, + {"transmute", &transmute_handler}, + {"rotate_left", &rotate_left_handler}, + {"rotate_right", &rotate_right_handler}, + {"wrapping_add", &wrapping_add_handler}, + {"wrapping_sub", &wrapping_sub_handler}, + {"wrapping_mul", &wrapping_mul_handler}, + {"copy_nonoverlapping", ©_nonoverlapping_handler}, + {"prefetch_read_data", &prefetch_read_data}, + {"prefetch_write_data", &prefetch_write_data}, +}; Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {} @@ -515,5 +541,58 @@ copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype) return fndecl; } +static tree +prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind) +{ + rust_assert (fntype->get_params ().size () == 2); + + tree lookup = NULL_TREE; + if (check_for_cached_intrinsic (ctx, fntype, &lookup)) + return lookup; + + auto fndecl = compile_intrinsic_function (ctx, fntype); + + // prefetching isn't pure and shouldn't be discarded after GIMPLE + TREE_READONLY (fndecl) = 0; + TREE_SIDE_EFFECTS (fndecl) = 1; + + std::vector<Bvariable *> args; + compile_fn_params (ctx, fntype, fndecl, &args); + + if (!ctx->get_backend ()->function_set_parameters (fndecl, args)) + return error_mark_node; + + enter_intrinsic_block (ctx, fndecl); + + auto addr = ctx->get_backend ()->var_expression (args[0], Location ()); + auto locality = ctx->get_backend ()->var_expression (args[1], Location ()); + + mpz_t zero; + mpz_t one; + mpz_init_set_ui (zero, 0); + mpz_init_set_ui (one, 1); + + auto rw_flag_value = kind == Prefetch::Write ? one : zero; + auto rw_flag + = ctx->get_backend ()->integer_constant_expression (integer_type_node, + rw_flag_value); + auto prefetch_raw = NULL_TREE; + auto ok + = BuiltinsContext::get ().lookup_simple_builtin ("prefetch", &prefetch_raw); + rust_assert (ok); + auto prefetch + = build_fold_addr_expr_loc (Location ().gcc_location (), prefetch_raw); + + auto prefetch_call + = ctx->get_backend ()->call_expression (prefetch, {addr, rw_flag, locality}, + nullptr, Location ()); + + ctx->add_statement (prefetch_call); + + finalize_intrinsic_block (ctx, fndecl); + + return fndecl; +} + } // namespace Compile } // namespace Rust |