From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id 03DB0384DD0D for ; Tue, 21 Feb 2023 12:03:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 03DB0384DD0D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x42b.google.com with SMTP id l1so3884803wry.10 for ; Tue, 21 Feb 2023 04:03:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=wlIGld7I7N2rxYXmhrMc0SdS9t1SlMANLJLEt/RxdnA=; b=V2vbMMkVjUNOydlfgaxmNuwNX74FHomxYLZKqPiN2eoDvIAqnXoQAeLabv7Xc732TA bJNE8UCWrA/v4WAWivJpJVtXyBrIpRRXr7CYmEd53TWG0keju5x18vJw4mROe/WDQTL2 FCONfKAnSN3dxPZjXG4IjDEyQav1b2PPPrtX8VC9S0sZrn5kpZH1A6+DxZs43FqLgr8E FPaIyuUB6c/DNnrBiWFNUvjZxBqnlpeQwzOQiMM8les/EqOylx9Vgx7R6J/4QPi/J9CV qgosU7MnkHoHwTcI/UcMSIg69ket1gnz8x/LMpcsgYR/3wGDJYLSvWdbj6kkJQfNzwC8 1y4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=wlIGld7I7N2rxYXmhrMc0SdS9t1SlMANLJLEt/RxdnA=; b=oe56+/vJLxWDhaiM0osLjNYgEjRvjEKSp1cz4mWuF/HtK6WnP4he49/9fUa8b6PP16 q7LGQ5aVFGZ5/OMl4Kt4SEe8k3kyM5wk1gwenmeB5lwQRzRyrewIVHoW1+6apu5txpMC N0P+XfGwXkPNQBXNupLbnWUHBd07VCl+2thxjQBk8bDbLLK25rDQtq9kao3e76BOWe8O y0g/KAWg0z/XsTJBRApagJYXvgdZWGiqoKw33WDQq8UJwRm2Opzz4KqS1rJPpP+EOeMF LtYbFPNK7JpR6JAVqy9Ivb4LVTFuKg30N4sx2mSne9UmSFieygnkWTYjNEr01YpFp1Wo ucVg== X-Gm-Message-State: AO0yUKXO0DyGmImOdDpX6T28U/wjs2d3sxsYsB6Yftp7UilH9+raq83z xQVYiE2E1J8BiIy5pzC0RyDS X-Google-Smtp-Source: AK7set8etQNenC8ZekzZ8er68GG2l1GOlFyBr5fzyMzktuQq2Z20p4Qmw8maPtE8tS28ITYVTBOl4Q== X-Received: by 2002:a5d:5045:0:b0:2c5:8a5a:fc01 with SMTP id h5-20020a5d5045000000b002c58a5afc01mr4263468wrt.11.1676981015773; Tue, 21 Feb 2023 04:03:35 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id c15-20020adffb4f000000b002c55b0e6ef1sm5013811wrs.4.2023.02.21.04.03.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 04:03:35 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [committed 015/103] gccrs: intrinsics: Add data prefetching intrinsics Date: Tue, 21 Feb 2023 13:01:05 +0100 Message-Id: <20230221120230.596966-16-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230221120230.596966-1-arthur.cohen@embecosm.com> References: <20230221120230.596966-1-arthur.cohen@embecosm.com> Reply-To: arthur.cohen@embecosm.com MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Arthur Cohen gcc/rust/ChangeLog: * backend/rust-builtins.cc (BuiltinsContext::setup): Declare prefetch intrinsics. * backend/rust-compile-intrinsic.cc (enum class Prefetch): Add kinds of prefetch intrinsics. (prefetch_data_handler): New function. (prefetch_read_data): Likewise. (prefetch_write_data): Likewise. gcc/testsuite/ChangeLog: * rust/execute/torture/prefetch_data.rs: New test. --- 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(-) create mode 100644 gcc/testsuite/rust/execute/torture/prefetch_data.rs 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 +} -- 2.39.1