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

Add llvm_asm! and deprecate asm! #2843

Merged
merged 4 commits into from
Mar 20, 2020
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions text/0000-llvm-asm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
- Feature Name: `llvm_asm`
- Start Date: 2019-12-31
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)

# Summary
[summary]: #summary

Deprecate the existing `asm!` macro and provide an identical one called
`llvm_asm!`. The feature gate is also renamed from `asm` to `llvm_asm`.

Unlike `asm!`, `llvm_asm!` is not intended to ever become stable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds a bit too strong, e.g, if we ever add a #[cfg(codegen_backed = "...")] macro to detect the code generation backend, then using llvm_asm! behind a #[cfg(codegen_backend = "llvm")] might make sense.

Suggested change
Unlike `asm!`, `llvm_asm!` is not intended to ever become stable.
Unlike `asm!`, `llvm_asm!` is currently perma unstable.

Also, if the feature is intended to be perma-unstable, at least for the time being, it might make sense to name the feature gate: feature(rustc_llvm_asm).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last that I checked (which was a while ago, mind), there are more objections to stabilizing the existing asm! macro than just its coupling to LLVM. Furthermore, if the proto-RFC for stable ASM were accepted and implemented it would be sufficiently different from the existing ASM support (both syntactically and semantically) that I feel people would be reluctant to stabilize the old version, if only for the sake of consistency.

This isn't to say anything about whether a stable llvm_asm! might be desirable; only that if it is desirable, it would likely not be served by merely stabilizing the existing ASM macro. I would expect such a discussion to be the purview of a totally separate RFC, although if the possibility isn't completely remote then that could suggest leaving the name llvm_asm! free for future use. I do like the idea of prepending "rustc" to things which are not intended to ever be stabilized... but really the "rustc" prefix should only be used for perma-unstable compiler implementation details, and unless rustc is using asm! (and I don't see why it would), I'd much prefer planning to remove the original asm! sometime after a replacement has been stabilized.

Copy link

@comex comex Jan 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My position is that the new asm! should be designed to provide substantially all of the functionality of the old one – and eventually more, such as an equivalent of C asm goto, which is supported by LLVM but not currently exposed in Rust.* After all... well, I don't want to downplay the complexity of implementing inline assembly in the first place. But since we are planning to do that, the question is how much additional complexity would be required to get from "basic support" to "full parity". As I see it, most of that complexity comes from two sources:

  1. The large amount of functionality supported by the assembler itself (e.g. directives, preprocessor)... but we're aiming to target existing assemblers, not create our own.

  2. The smorgasbord of arch-dependent constraint codes supported by GCC... but LLVM only supports a small fraction of them anyway, and we only need to match LLVM's support.

So it should be feasible to reach pretty much full parity. At that point, llvm_asm! will be redundant, and I think it's fine to plan to remove it. That said, there would be no urgent need to remove it; it should be possible to have a long deprecation period, and there might even be a case for keeping it indefinitely for experimentation purposes... but that would have to be weighed against the compiler maintenance burden.

* For anyone who hasn't been following discussions, that doesn't mean adding goto to Rust; we just need some way to express the concept of jumping out of asm blocks, which would most likely resemble a match statement.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing we need to unblock progress on the new inliner assembler is to rename the asm! macro to llvm_asm!, although as exposed here it also makes sense to rename the feature gate.

While I mostly agree with what you said, we don't really need to make any commitments right now about the future of llvm_asm!, so we can just punt that discussion.


# Motivation
[motivation]: #motivation

This change frees up the `asm!` macro so that it can be used for the new
`asm!` macro designed by the inline asm project group while giving existing
users of `asm!` an easy way to keep their code working.

It may also be useful to have an inline asm implementation available
(on nightly) for architectures that the new `asm!` macro does not support yet.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

The Rust team is currently in the process of redesigning the `asm!` macro.
You should replace all uses of `asm!` with `llvm_asm!` in your code to avoid breakage when the new `asm!` macro is implemented.

# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation

All references to `asm!` inside the compiler will be changed to refer to `llvm_asm!` instead.
`asm!` will become a simple (deprecated) `macro_rules!` which redirects to `llvm_asm!`.
The deprecation warning will advise users that the semantics of `asm!` will change in the future and invite them to use `llvm_asm!` instead.

# Drawbacks
[drawbacks]: #drawbacks

This change may require people to change their code twice: first to `llvm_asm!`, and then to the new
`asm!` macro once it is implemented.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

We could skip the deprecation period and perform the renaming at the same time the new `asm!` macro
is implemented. However this is guaranteed to break a lot of code using nightly Rust at once without
any transition period.

# Prior art
[prior-art]: #prior-art

The D programming language also support 2 forms of inline assembly. The [first one][d-asm] provides an embedded DSL
for inline assembly, which allows direct access to variables in scope and does not require the use of clobbers, but is only available on x86 and x86_64. The [second one][d-llvm-asm] is a raw interface to LLVM's internal inline assembly syntax, which is available on all architectures but only on the LDC backend.

[d-asm]: https://dlang.org/spec/iasm.html
[d-llvm-asm]: https://wiki.dlang.org/LDC_inline_assembly_expressions

# Unresolved questions
[unresolved-questions]: #unresolved-questions

- Should the deprecated `asm!` macro be under the `asm` or `llvm_asm` feature gate?

# Future possibilities
[future-possibilities]: #future-possibilities

When the [new `asm!` macro][inline-asm-rfc] is implemented it will replace the current one. This
will break anyone who has not yet transitioned their code to `llvm_asm!`. No
silent miscompilations are expected since the operand separator will be changed
from `:` to `,`, which will guarantee that any existing `asm!` invocations will
fail with a syntax error with the new `asm!` macro.

[inline-asm-rfc]: https://github.com/rust-lang/project-inline-asm/blob/master/rfcs/0000-inline-asm.md