-
Notifications
You must be signed in to change notification settings - Fork 498
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
Clearly specify the instruction_set
effects
#1307
Conversation
Nominating for a quick skim from T-lang. In particular, the rules around inlining, starting here: are we okay with this set of rules? There are three basic rules there, the first two dictating the cases where inlining will be disallowed, and the third dictating when inlining will be allowed (and thus the calling function must not rely on details of the instruction set, or at least not details that would be in conflict with the instruction set of the callee that is being inlined). The two specific questions are:
|
I should perhaps note that if a function is inlined in some places as well as being fully generated to call over to from other places, the generated version will be of the target's default instruction set as one would expect. The goal here is to carve out a little wiggle room for the MIR inliner to do more work. Without the ability to inline no-attribute code into attribute'd code it makes any use of the attribute a complete drop in performance. For more background on how we got here you can also read the zulip topic: https://rust-lang.zulipchat.com/#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/What.20exactly.20does.20the.20MIR.20optimizer.20do.3F |
Hey @Lokathor , sorry for the long delay in response here The T-lang design team talked about this PR in its triage meeting yesterday No one at the meeting expressed any problem with the rules as stated. There was a slight concern about whether the language here is potentially misleading: we already don't say what inlining exactly "means", and all discussions of inlining attributes repeatedly say that they are all merely hints, with no requirements that inlining actually happen, or actually be strictly prohibited. So, there was some feedback about whether this text could try incorporate that notion (redundantly, I acknowledge). In other words, we wish for it to be clear that this text is non-normative, and is just meant to set users expectations about what might happen, without making strict guarantees in one direction or the other. |
Also, there was some followup discussion on zulip in that conversation, while attempting to summarize the meaning of the third rule, I wrote the something like the following:
and there was some feedback indicating that this is a better way to write the third rule in question, with the belief that the resulting effects on whether inlining is allowed or not falls out naturally from that phrasing. Maybe the third rule can instead be pulled out and phrased in something like the above form, and then you can keep the discussion of inlining, including all three parts, but reframe it all as consequences of the new phrasing? |
Ah, slipped my mind, I'll try to get to this soon |
I think the new wording is sufficiently improved? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some editorial nits.
@pnkfelix Did you have any comments on the updated text? Do you want to start an FCP to formally approve the changes, or was the team discussion sufficient? |
Co-authored-by: Eric Huss <eric@huss.org>
Co-authored-by: Eric Huss <eric@huss.org>
@rustbot labels +I-lang-nominated Raising for team discussion. I think that this text is fine as is. This whole feature is on that "grey line" where it doesn't theoretically affect language semantics etc etc. |
src/attributes/codegen.md
Outdated
@@ -374,4 +375,9 @@ fn foo_arm_code() {} | |||
fn bar_thumb_code() {} | |||
``` | |||
|
|||
[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax | |||
If your function has neither the `instruction_set` attribute nor inline assembly, then the code you write within that function should not presume any particular instruction set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your function has neither the `instruction_set` attribute nor inline assembly, then the code you write within that function should not presume any particular instruction set. | |
If your function has neither the `instruction_set` attribute nor inline assembly, and you're compiling for a target with multiple instruction sets, the code you write within that function should not presume any particular instruction set. |
src/attributes/codegen.md
Outdated
|
||
* If a function has an `instruction_set` attribute it won't inline into a function of another instruction set. | ||
* If a function does not have an `instruction_set` attribute but *does* contain inline assembly, then the inline assembly is assumed to require the default instruction set of the build target, and so inlining between different instruction sets won't happen. | ||
* Otherwise, inlining happens normally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it's specific to ARM and Thumb; this may not necessarily universally be true for all future uses of instruction_set
.
src/attributes/codegen.md
Outdated
@@ -374,4 +375,9 @@ fn foo_arm_code() {} | |||
fn bar_thumb_code() {} | |||
``` | |||
|
|||
[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax | |||
If your function has neither the `instruction_set` attribute nor inline assembly, then the code you write within that function should not presume any particular instruction set. | |||
This ends up creating a limitation to how often code is inlined: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ends up creating a limitation to how often code is inlined: | |
For ARM in particular, `instruction_set` adds a limitation to where code gets inlined: |
I don't think the reference should make any mention of inlining, since that is an implementation detail. Instead the text should clearly document the actual guaranteed effects of
The restrictions on inlining are mainly an artifact of how inline assembly is compiled with LLVM: it uses the instruction set of the containing function after ininling. As such we need to ensure that any functions containing inline assembly are not inlined into functions with a different instruction set. |
@joshtriplett updated per the 2023-06-27 T-lang meeting, ready for FCP if the text seems fine. |
@rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
The PR description and title still need to be updated to the new content. |
instruction_set
inlining restrictionsinstruction_set
effects
should be fixed |
@rfcbot reviewed |
🔔 This is now entering its final comment period, as per the review above. 🔔 psst @joshtriplett, I wasn't able to add the |
@rustbot labels -I-lang-nominated +final-comment-period |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. psst @joshtriplett, I wasn't able to add the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks everyone!
Update books ## rust-lang/book 3 commits in 668c64760b5c7ea654facb4ba5fe9faddfda27cc..72187f5cd0beaaa9c6f584156bcd88f921871e83 2023-08-04 14:42:07 UTC to 2023-08-03 13:36:44 UTC - redirects: change link for the `#![no_std]` tutorial (rust-lang/book#3705) - [chpt10.2] - Small wording changes (rust-lang/book#3724) - Improve sentence (rust-lang/book#3725) ## rust-embedded/book 1 commits in 1e5556dd1b864109985d5871616ae6b9164bcead..99ad2847b865e96d8ae7b333d3ee96963557e621 2023-08-11 06:31:04 UTC to 2023-08-11 06:31:04 UTC - Fix a small typo in qemu.md (rust-embedded/book#359) ## rust-lang/nomicon 1 commits in 302b995bcb24b70fd883980fd174738c3a10b705..388750b081c0893c275044d37203f97709e058ba 2023-08-10 21:15:21 UTC to 2023-08-10 21:15:21 UTC - Document thiscall abi (rust-lang/nomicon#311) ## rust-lang/reference 10 commits in 1ea0178266b3f3f613b0fabdaf16a83961c99cdb..d43038932adeb16ada80e206d4c073d851298101 2023-08-12 19:07:28 UTC to 2023-07-16 20:12:46 UTC - Document thiscall abi (rust-lang/reference#1092) - add section about implied bounds (rust-lang/reference#1261) - Clearly specify the `instruction_set` effects (rust-lang/reference#1307) - Fix merge queue building twice. (rust-lang/reference#1383) - Clarify UB around immutability & mutation (rust-lang/reference#1385) - mention the extra const UB (rust-lang/reference#1273) - Operator expressions: make the note about division by zero clearer. (rust-lang/reference#1384) - Make unsafe keyword docs less confusing (rust-lang/reference#1379) - Say that division by zero for primitive types panics (rust-lang/reference#1382) - Add CI trigger for merge queues. (rust-lang/reference#1381) ## rust-lang/rust-by-example 3 commits in 8a87926a985ce32ca1fad1be4008ee161a0b91eb..07e0df2f006e59d171c6bf3cafa9d61dbeb520d8 2023-07-24 11:37:55 UTC to 2023-07-24 11:35:36 UTC - Added attribute unused_labels - fixed warning. (rust-lang/rust-by-example#1729) - more explanation about panic (rust-lang/rust-by-example#1728) - chore: add the portuguese version of this project to `readme.md` (rust-lang/rust-by-example#1727) ## rust-lang/rustc-dev-guide 31 commits in b5a12d9..b123ab4 2023-08-14 08:34:59 UTC to 2023-07-11 06:02:34 UTC - fix: stabilize debugger_visualizer (rust-lang/rustc-dev-guide#1766) - feat(part-5-intro): make "Part 5" obvious (rust-lang/rustc-dev-guide#1753) - Update from `#[warn_]` to `#[warning]` diagnostic attributes (rust-lang/rustc-dev-guide#1765) - Add RPITIT documentation (rust-lang/rustc-dev-guide#1764) - fix(visitor.md): fix a type name in a code sample (rust-lang/rustc-dev-guide#1762) - fix(name-resolution): remove unnecessary closing paranthesis (rust-lang/rustc-dev-guide#1760) - fix(macro-expansion.md): fix the article `an` to `a` (rust-lang/rustc-dev-guide#1759) - fix(serialization.md): fix the name of a derive macro (rust-lang/rustc-dev-guide#1756) - fix(serialization.md): add a necessary plural suffix (rust-lang/rustc-dev-guide#1757) - fix(salsa.md): add punctuation to prevent confusion (rust-lang/rustc-dev-guide#1754) - fix(salsa.md): remove duplicate "To Be" verb (rust-lang/rustc-dev-guide#1755) - feat(fuzzing.md): make `halfempty` word a link (rust-lang/rustc-dev-guide#1750) - fix(about.md): use `a` instead of `an` (rust-lang/rustc-dev-guide#1751) - refactor(git.md): make git-scm links clickable (rust-lang/rustc-dev-guide#1747) - fix(walkthrough.md) add a comma operator to eliminate ambiguity (rust-lang/rustc-dev-guide#1749) - fix(git.md): remove a confusing end of sentence character (rust-lang/rustc-dev-guide#1748) - refactor(profiling/with_perf): remove a wrong to be verb (rust-lang/rustc-dev-guide#1746) - refactor(tests/headers): remove duplicate list item (rust-lang/rustc-dev-guide#1745) - refactor(test/headers.md): make the meaning more obvious (rust-lang/rustc-dev-guide#1744) - refactor(tests/ui): remove unnecessary duplicate word (rust-lang/rustc-dev-guide#1743) - refactor(compiletest): remove unnecessary duplicate word (rust-lang/rustc-dev-guide#1742) - generic_arguments.md: substs -> GenericArgs (rust-lang/rustc-dev-guide#1741) - fix(suggested): remove an unnecessary and confusing statement (rust-lang/rustc-dev-guide#1739) - fix(how-to-build-and-run): fix a typo ("fromer" -> "former") (rust-lang/rustc-dev-guide#1736) - fix(how-to-build-and-run): remove a wrong paragraph (rust-lang/rustc-dev-guide#1735) - coverage code has moved (rust-lang/rustc-dev-guide#1728) - linked issue is closed (rust-lang/rustc-dev-guide#1729) - remove duplicate reference in about-this-guide.md (rust-lang/rustc-dev-guide#1734) - Explain more in depth what early and late bound generic parameters are (rust-lang/rustc-dev-guide#1732) - add section for normalization with the new solver (rust-lang/rustc-dev-guide#1731) - Improve cleanup-crew.md with an example post (rust-lang/rustc-dev-guide#1730)
This updates theinstruction_set
attribute entry to more clearly explain the additional restrictions that the attribute places on inlining. Since Rust performance heavily relies on inlining, it's actually a fairly big deal to document it.Pinging @pnkfelix as the liaison for theinstruction_set
attribute during its development.This explanation is actually slightly looser than the explanation given in the RFC: this explanation allows inlining between no-attribute code without inline asm and other code. So, T-lang should likely approve the update with an FCP or similar process. The intent is that once this is approved as the documentation for how the attribute works then rust-lang/rust#104121 (which updates the MIR inliner to match these rules) will be easier to land.Updates the attributes page to specify what the
instruction_set
attribute does and where you can use it.