Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd new #[target_feature = "..."] attribute. #38079
Conversation
rust-highfive
assigned
pnkfelix
Nov 30, 2016
This comment has been minimized.
This comment has been minimized.
|
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
rust-highfive
assigned
alexcrichton
and unassigned
pnkfelix
Nov 30, 2016
This comment has been minimized.
This comment has been minimized.
|
Here are some questions/comments/concerns:
I don't know whether any of the above should be fixed before merging. Certainly, they should at least be fixed/addressed before stabilization. |
This comment has been minimized.
This comment has been minimized.
|
cc @eddyb |
This comment has been minimized.
This comment has been minimized.
eddyb
reviewed
Nov 30, 2016
| @@ -60,11 +62,10 @@ pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) { | |||
| // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a | |||
| // parameter. | |||
| if ccx.sess().must_not_eliminate_frame_pointers() { | |||
| let name = CString::new("no-frame-pointer-elim").unwrap(); | |||
| let val = CString::new("true").unwrap(); | |||
This comment has been minimized.
This comment has been minimized.
| for attr in attrs { | ||
| if attr.check_name("cold") { | ||
| if attr.check_name("target_feature") { | ||
| let val = attr.value_str().map_or(String::new(), |s|s.to_string()); |
This comment has been minimized.
This comment has been minimized.
eddyb
Nov 30, 2016
Member
This shouldn't allocate. You can use let val = attr.value_str().map(|s| s.as_str()); ... val.map_or("", |s| &s[..]).split(",").
This comment has been minimized.
This comment has been minimized.
BurntSushi
Nov 30, 2016
Author
Member
It turns out this doesn't work because s is an InternedString. I just took the hit with the extra case analysis instead.
| for feat in val.split(",") { | ||
| let feat = feat.trim().to_string(); | ||
| if !feat.is_empty() && !feat.contains('\0') { | ||
| target_features.push(feat); |
This comment has been minimized.
This comment has been minimized.
eddyb
Nov 30, 2016
Member
You can move the .to_string() on this line, or push to a String instead of allocating for each one.
| @@ -88,4 +97,10 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe | |||
| unwind(llfn, true); | |||
| } | |||
| } | |||
| if !target_features.is_empty() { | |||
| let name = CString::new("target-features").unwrap(); | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
BurntSushi
Nov 30, 2016
•
Author
Member
Yeah, I just didn't really care about the allocation. I'll fix them. :-)
This comment has been minimized.
This comment has been minimized.
|
The x86 whitelist has ramifications elsewhere for the stable name of these features. The intention is that we ourselves maintain a mapping of features to the actual LLVM names, so that way if LLVM changes a name we can just update our implementation but the name we present to Rust is always stable. In that sense could we perhaps be more conservative with the update to the x86 whitelist? Perhaps only the features needed for SIMD progress for now? |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton Ah whoops! I will trim it back down to what it was, but I think we should add at least |
This comment has been minimized.
This comment has been minimized.
|
(We will definitely want to add more from that list at time moves on. AVX512 has a particularly large presence, but I think we should punt on AVX512 for this initial push. It it absolutely gigantic.) |
BurntSushi
force-pushed the
BurntSushi:attrtarget
branch
from
e46652a
to
80ef1db
Nov 30, 2016
This comment has been minimized.
This comment has been minimized.
|
I think I'd agree that we should require target_feature functions to be unsafe. EDIT: Hmm, maybe not - I don't think you'd see anything worse than a crash, and a crash isn't memory unsafe, right? |
This comment has been minimized.
This comment has been minimized.
|
To be more precise, I think the failure mode is that your program attempts to execute an instruction that the CPU doesn't recognize. Is this behavior actually defined to always crash your program? |
This comment has been minimized.
This comment has been minimized.
|
@BurntSushi If the kernel doesn't emulate it then you get a SIGILL on most UNIX systems (I would hope). |
This comment has been minimized.
This comment has been minimized.
|
If you attempt to execute an illegal instruction on Windows, a |
This comment has been minimized.
This comment has been minimized.
|
Note that "target-features" function attribute is undocumented. So while LLVM is unstable, this attribute is extra unstable, even unstable by LLVM standard. At least in 2015, a bug about "target-features" function attribute was closed as "LATER". See LLVM bug 22081. Hopefully this changed, but I haven't seen any announcement. Did anyone? |
This comment has been minimized.
This comment has been minimized.
|
@sanxiyn If it's good enough for Clang and LDC, is it good enough for Rust? (I note that gcc seems to support a similar---possibly identical---feature.) As a side note, our current trajectory for SIMD stabilization hinges pretty critically on I don't know what the proper channels are to inquire about something like this. |
This comment has been minimized.
This comment has been minimized.
|
I am simply pointing out two things. One, the attribute is unstable in LLVM. Of course, that doesn't mean it can't be stable in Rust. In principle, Rust is already using LLVM C++ API, which is also unstable. Two, |
This comment has been minimized.
This comment has been minimized.
|
r+ from me on this. I'm fine on punting on requiring I'm also fine using something unstable in LLVM, especially in an unstable API. Presumably the clang feature of @eddyb do all the trans pieces here look good to you? |
This comment has been minimized.
This comment has been minimized.
|
Yeah, it looks good to me. |
This comment has been minimized.
This comment has been minimized.
|
Ok @bors: r+ |
This comment has been minimized.
This comment has been minimized.
|
|
BurntSushi commentedNov 30, 2016
•
edited
This commit adds a new attribute that instructs the compiler to emit
target specific code for a single function. For example, the following
function is permitted to use instructions that are part of SSE 4.2:
In particular, use of this attribute does not require setting the
-C target-feature or -C target-cpu options on rustc.
This attribute does not have any protections built into it. For example,
nothing stops one from calling the above
foofunction on hosts withoutSSE 4.2 support. Doing so may result in a SIGILL.
I've also expanded the x86 target feature whitelist.