From 0006203aa910d2ca9ce94bbb64b03241b408a0ac Mon Sep 17 00:00:00 2001 From: "Hadrien G." Date: Fri, 14 Jun 2024 07:43:53 +0200 Subject: [PATCH] Finally implement Pessimize for slices on stable --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 11 +++++++++++ Cargo.toml | 4 ++-- README.md | 2 +- src/ptr.rs | 41 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2041db9..6d883b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ concurrency: env: RUSTFLAGS: -D warnings RUSTDOCFLAGS: -D warnings - MINIMAL_RUST: 1.63.0 # Minimal Supported Rust Version + MINIMAL_RUST: 1.79.0 # Minimal Supported Rust Version jobs: # Workaround for github CI dropping env var expansion in matrix strategy diff --git a/CHANGELOG.md b/CHANGELOG.md index 87bfc6d..e4f8cc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 _There are no unreleased changes in the pipeline at the moment._ +## [2.0.0] - 2024-06-14 + +### Added + +- Implement Pessimize for slices. + +### Changed + +- Bumped MSRV to 1.79.0. + + ## [1.0.1] - 2024-02-12 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 0c19bd4..913ac5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,14 +11,14 @@ name = "pessimize" # - Roll an annotated git tag # - Add a github release # -version = "1.0.1" +version = "2.0.0" authors = ["Hadrien G. "] description = "More efficient Rust compiler optimization barriers" keywords = [ "optimization", "barrier", "black-box", "efficient", "benchmarking" ] categories = [ "development-tools", "hardware-support", "no-std", "rust-patterns" ] license = "MPL-2.0" edition = "2021" -rust-version = "1.63.0" +rust-version = "1.79.0" [features] default = ["std"] diff --git a/README.md b/README.md index 63b3900..8c98024 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Continuous Integration](https://img.shields.io/github/actions/workflow/status/HadrienG2/pessimize/ci.yml?branch=master)](https://github.com/HadrienG2/pessimize/actions?query=workflow%3A%22Continuous+Integration%22) ![Requires rustc -1.63.0+](https://img.shields.io/badge/rustc-1.63.0+-lightgray.svg) +1.79.0+](https://img.shields.io/badge/rustc-1.79.0+-lightgray.svg) Microbenchmarking is a subtle exercise to begin with, and the lack of lightweight optimization barriers on stable Rust makes it even more difficult. diff --git a/src/ptr.rs b/src/ptr.rs index 75290ee..32e2c1e 100644 --- a/src/ptr.rs +++ b/src/ptr.rs @@ -32,10 +32,11 @@ fn assume_accessed_thin_ptr(x: *mut T) { unsafe { core::arch::asm!("/* {0} */", in(reg) x, options(preserves_flags, nostack)) } } -// Implementation of Pessimize for thin *const T +// Implementation of Pessimize for thin *const T and *const [T] #[cfg(not(feature = "nightly"))] mod thin_pointers { use super::*; + use core::ptr; // Safe because the functions above are implemented as expected // @@ -62,6 +63,44 @@ mod thin_pointers { assume_accessed_thin_ptr(*self as *mut T); } } + + // Safe because the functions above are implemented as expected + // + // This is one of the primitive Pessimize impls on which the + // PessimizeCast/BorrowPessimize stack is built + unsafe impl Pessimize for *const [T] { + #[inline] + fn hide(self) -> Self { + let (data, len) = slice_to_raw_parts(self); + ptr::slice_from_raw_parts(hide_thin_ptr(data), crate::hide(len)) + } + + #[inline] + fn assume_read(&self) { + let (data, len) = slice_to_raw_parts(*self); + assume_read_thin_ptr(data.cast::<()>()); + crate::consume(len) + } + + #[inline] + fn assume_accessed(&mut self) { + let (data, mut len) = slice_to_raw_parts(*self); + assume_accessed_thin_ptr(data.cast::<()>().cast_mut()); + assume_accessed(&mut len); + // Correct because hide is identity and assume_accessed doesn't modify + *self = ptr::slice_from_raw_parts(data, len) + } + + #[inline] + fn assume_accessed_imut(&self) { + assume_accessed_thin_ptr(self.cast::<()>().cast_mut()); + // NOTE: It's not legal to change the length of a slice from &self + } + } + + fn slice_to_raw_parts(slice: *const [T]) -> (*const T, usize) { + (slice.cast::(), slice.len()) + } } // #[cfg(feature = "nightly")]