From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 8597C3858425; Mon, 10 Oct 2022 07:33:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8597C3858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665387233; bh=IzwvW49+S2i592KjVSzrX54oaKGT5nGrABsNWcqPV8M=; h=From:To:Subject:Date:From; b=KQvEJ0203XO7Z6Q7EAbdxYYGI8BNSB4E/LMA2G7pbG21YQOr4EjxGDCgkaTwC1rS0 ph8eMOkl7UzgAqH3XiCsRNXRKPreJVG/nzLeV+D1eh+sm81tkgPBQ0PdZykaV4O+A0 4FhvlMl5+YNH2qxEhmVAslxOsPxKGb3rTPqJK0/M= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] intrinsics: Add data prefetching intrinsics X-Act-Checkin: gcc X-Git-Author: Arthur Cohen X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: b4096017e3b9ca499b56988b67e05667a02ca202 X-Git-Newrev: 71397abfbe573beee3415e7031bcea84d80cdd6e Message-Id: <20221010073353.8597C3858425@sourceware.org> Date: Mon, 10 Oct 2022 07:33:53 +0000 (GMT) List-Id: https://gcc.gnu.org/g:71397abfbe573beee3415e7031bcea84d80cdd6e commit 71397abfbe573beee3415e7031bcea84d80cdd6e Author: Arthur Cohen Date: Wed Oct 5 17:49:44 2022 +0200 intrinsics: Add data prefetching intrinsics Diff: --- gcc/rust/backend/rust-builtins.cc | 6 ++ gcc/rust/backend/rust-compile-intrinsic.cc | 97 ++++++++++++++++++++-- .../rust/execute/torture/prefetch_data.rs | 17 ++++ 3 files changed, 111 insertions(+), 9 deletions(-) diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc index 14dc037edac..d6f8cb6f495 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 616919677c9..a418b863210 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> - 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 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 diff --git a/gcc/testsuite/rust/execute/torture/prefetch_data.rs b/gcc/testsuite/rust/execute/torture/prefetch_data.rs new file mode 100644 index 00000000000..dc049b136dd --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/prefetch_data.rs @@ -0,0 +1,17 @@ +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn prefetch_read_data(addr: *const T, locality: i32); + fn prefetch_write_data(addr: *const T, locality: i32); +} + +fn main() -> i32 { + let a = [1, 2, 3, 4]; + + unsafe { + prefetch_read_data(&a, 3); + prefetch_write_data(&a[0], 3); + } + + 0 +}