Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target feature runtime #2725

Open
wants to merge 8 commits into
base: master
from

Conversation

@gnzlbg
Copy link
Contributor

commented Jul 15, 2019

Rendered


This RFC proposes exporting the target-feature detection macros (e.g. is_x86_feature_detected!) from libcore, enabling all Rust libraries, including #![no_std] libraries, to use them. It works out the details of the implementation, and propose to make parts of it public to allow #![no_std] binaries and libstd to provide their own target-feature-detection run-times via these APIs.

This RFC can be stabilized in stages. We can stabilize the exporting of the target-feature detection macros from libcore without stabilizing anything else, since the standard library and #![no_std] libraries can both use unstable Rust features. Once we start working on the stabilization of #![no_std] binaries, we can revisit the stabilization of these APIs.

SSE3. In Rust, we call `x86_64` the target architecture "family", and extensions
like SSE2 or SSE3 "target-features".

Many Rust applications compiled for `x86_64-unknonw-linux-gnu` do want to use

This comment has been minimized.

Copy link
@bjorn3

bjorn3 Jul 18, 2019

Suggested change
Many Rust applications compiled for `x86_64-unknonw-linux-gnu` do want to use
Many Rust applications compiled for `x86_64-unknown-linux-gnu` do want to use
* Should the `libstd` run-time be overridable? For example, by only providing it
if no other crate in the dependency graph provides a runtime ? This would be a
forward-compatible extension, but no use case considered requires it.

This comment has been minimized.

Copy link
@bjorn3

bjorn3 Jul 18, 2019

  • Does core::detect::is_target_feature_detected cache the result of core::detect::TargetFeatureRuntime::is_feature_detected or is the later responsible for caching itself?
@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

commented Jul 18, 2019

@therealprof

This comment has been minimized.

Copy link

commented Jul 23, 2019

Sounds good to me.

One thing I couldn't quite find in the RFC is how this actually bridges between runtime and compile-time detection, i.e. how the macro in libcore will help to move crates over to no_std without introducing runtime overhead for details known at compile time as mentioned in the introduction. Also I'm confused as to how this will work in practise since using the macro in a condition might still cause code to be emitted, causing the generation of instructions which are denied by later stages of the compilation or by the linker due to incompatibility with the target.

And regarding the feature detection, is everyone supposed to roll their own or is there going to be a good default implementation like for the panic handling and liballoc?

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

commented Jul 23, 2019

i.e. how the macro in libcore will help to move crates over to no_std without introducing runtime overhead for details known at compile time

The macros already do that, e.g., the libstd docs guarantees that the macros resolve at compile-time if the feature is known to be enabled at compile-time.


using the macro in a condition might still cause code to be emitted,

This is already the case even if you use compile-time feature detection via if cfg!(target_feature = "avx") { ... }, where the macro there expands either to true or false. It is up to the users to choose an optimization level / backend that removes dead code.

If you want to make sure that no run-time detection actually ever happens, you could implement your own run-time that just calls panics, e.g., by calling unreachable!(), or if you know that no run-time detection macro will be called in your program you could go as far as using core::hint::unreachable_unchecked if you are feeling brave.


are denied by later stages of the compilation or by the linker due to incompatibility with the target.

I'm not sure if this will answer your question, but the macros are only available for targets that support them. If a target does not support them, there is no macro for users to use, so what you describe cannot currently happen.

That is, if you want to use is_x86_feature_detected!, you need to guard the use with a #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] or the code won't compile on any other target because that macro does not exist.

And regarding the feature detection, is everyone supposed to roll their own or is there going to be a good default implementation like for the panic handling and liballoc?

Currently, the std::detect implementation is available in crates.io as the std_detect crate, and is quiet configurable. If that does not solve your use case, you can roll your own, and others might find it useful.

@therealprof

This comment has been minimized.

Copy link

commented Jul 23, 2019

This is already the case even if you use compile-time feature detection via if cfg!(target_feature = "avx") { ... }, where the macro there expands either to true or false. It is up to the users to choose an optimization level / backend that removes dead code.

That seems like a bad idea. People not being able to use dev builds because optimized code paths using this feature will not be linkable due to code not being removed.

We do see a lot of such problems in no_std land today, e.g. CAS instructions finding their way into code compiled for ARM Thumb v6-M, not even to mention that unused code emitted in dev builds which is not collected is always troublesome for embedded due to limited flash size...

That is, if you want to use is_x86_feature_detected!, you need to guard the use with a #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] or the code won't compile on any other target because that macro does not exist.

It would be way more convenient if that was implicit (or at least there's a separate version with implicit feature gates). Requiring to manually pair those seems like a perfect way to cause seemingly random build errors and wrong code paths being used. Done properly this would also eliminate my concern above...

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

commented Jul 23, 2019

That seems like a bad idea. People not being able to use dev builds because optimized code paths using this feature will not be linkable due to code not being removed. [...]

The runtime target-feature detection macros currently only allow detecting features for which this cannot happen.

It would be way more convenient if that was implicit (or at least there's a separate version with implicit feature gates). Requiring to manually pair those seems like a perfect way to cause seemingly random build errors and wrong code paths being used. Done properly this would also eliminate my concern above...

This RFC does not require doing that.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2019

@therealprof this RFC only proposes allowing users to configure the run-time component of the target-feature detection system. That system has already been RFC'ed, and is implemented on both stable and nightly for half a dozen targets (including embedded ones) and dozens of target features. This RFC does not change anything about how any of that currently works. That is out-of-scope.

If you have questions about that system, the docs are usually a good place to start, but you can also go through the RFCs (e.g. the std::arch RFC or the target-feature RFC).

@therealprof

This comment has been minimized.

Copy link

commented Jul 25, 2019

It's okay, I was reading a bit more into the preamble than this RFC is about. It's still a useful proposal, just not as useful for me as I'd had hoped from my initial reading. 😉

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2019

It's still a useful proposal, just not as useful for me as I'd had hoped from my initial reading.

It might be out-of-scope/offtopic for this RFC, but would it be possible for you to open an issue in this repo about which problem you need to solve ? We can try to figure out how to do that there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.