Skip to content

Candidate Target Policy #3145

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

joshtriplett
Copy link
Member

@joshtriplett joshtriplett commented Jun 27, 2021

This RFC introduces a policy for targets not yet ready to merge into Rust, to allow for initial coordination and consensus-seeking.

Rust teams or team members sometimes have informal discussions with the developers of various candidate targets, to coordinate and build consensus on the requirements needed to later upstream the target, and to determine properties of the target such as the ABI and target name. However, such informal discussions do not typically get recorded in any official location, and may not be coordinated among the broader Rust project.

This policy (the "Candidate Target Policy") allows for the formal evaluation of a candidate target for Rust, and the acceptance of such a target as a "Candidate Target". It has a lower threshold than even the "Tier 3" target requirements, while still serving to start a conversation and reach some initial consensus on compatibility.

For example, an approval of a Candidate Target may nail down the target name (the "triple"); this helps avoid the situation where other tools begin using a name and that name becomes more difficult to change. An approval of a Candidate Target may additionally nail down the sizes and alignments of various types, and how those types are passed in the C ABI, to allow coordination among other tools generating code for the target.

There are many potential names we could use for such targets. Thanks to @clarfonthey for suggesting the name "Candidate Target". (This was renamed from "Potential Target".) The ideal name should avoid any implication of upcoming/impending inclusion of the target; for instance, "Future Target" could have such implications. "Add xyz as a Candidate Target" seems like an accurate description of what this process will enable.

This RFC introduces a policy for targets not yet ready to merge into
Rust, to allow for initial coordination and consensus-seeking.

Rust teams or team members sometimes have informal discussions with the
developers of various potential targets, to coordinate and build
consensus on the requirements needed to later upstream the target, and
to determine properties of the target such as the ABI and target name.
However, such informal discussions do not typically get recorded in any
official location, and may not be coordinated among the broader Rust
project.

This policy (the "Potential Target Policy") allows for the formal
evaluation of a potential target for Rust, and the acceptance of such a
target as a "Potential Target". It has a lower threshold than even the
"Tier 3" target requirements, while still serving to start a
conversation and reach some initial consensus on compatibility.

For example, an approval of a Potential Target may nail down the target
name (the "triple"); this helps avoid the situation where other tools
begin using a name and that name becomes more difficult to change. An
approval of a Potential Target may additionally nail down the sizes and
alignments of various types, and how those types are passed in the C
ABI, to allow coordination among other tools generating code for the
target.

There are many potential names we could use for such targets. I chose
"Potential Target" over names like "Future Target" to avoid any
implication of upcoming/impending inclusion of the target. "Add xyz as
a Potential Target" seems like an accurate description of what this
process will enable.
@joshtriplett joshtriplett added T-lang Relevant to the language team, which will review and decide on the RFC. T-compiler Relevant to the compiler team, which will review and decide on the RFC. labels Jun 27, 2021
@clarfonthey
Copy link

Not to bikeshed, but "candidate target" might be a better term since it's less ambiguous whether it's (potential target) policy or potential (target policy).

@joshtriplett
Copy link
Member Author

I think that same ambiguity applies to most "adjective target policy" combinations, but I do like "candidate target" quite a bit. I may end up switching to that.

@joshtriplett joshtriplett changed the title Potential Target Policy Candidate Target Policy Jun 29, 2021
@petrochenkov
Copy link
Contributor

Any specific examples of such targets past, present or future?

@joshtriplett
Copy link
Member Author

@petrochenkov rust-gpu has a whole family of targets, for which it'd help to nail down some of the details. Solana has a variant of the BPF target, which needs a modified LLVM. I expect several new targets to become possible once rustc_codegen_gcc gets merged.

@chorman0773
Copy link

chorman0773 commented Jul 8, 2021

I have some questions to raise:

  • There must be a concrete plan to develop the Candidate Target

Would this include development for targets under current or future implementations that are not rustc? For example, if the target is infiesable to implement in rustc (overly burdensome to add an llvm target for, and not supported in upstream gcc), would that preclude the addition of the target as a Candidate Target? If so, what process would be taken for such targets, and would implementations be barred from providing such targets if/while such a process does not exist? For example, could a fictional m6502-mos-cc65 target be introduced without plans to support the cc65 abi in gcc or llvm, and without the burden of adding a backend to rustc (which may or may not be fun for cc65).

  • If the target proposes an ABI different from that of any existing Rust target (such as in the sizes or alignments of standard types), the proposal must be approved by the Rust language team, who will evaluate whether the acceptance of the target would meet the semantic requirements of the language, and avoid adverse effects on the Rust ecosystem.

I'm worried whether the Lang Team will have much to do other than say "yes we can add this target vs. no we cannot". If much of those details have been determined and implemented in a C compiler and code in the wild uses that C compiler, it would be highly difficult to change. Otherwise, people looking to add new rust targets would have to bring the consideration before significant work on a C implementation begins, and it could end up as T-lang now having to sign off on the ABI present in a C compiler. It also means it would be a significant burden if adding support to a target that already has a C compiler with which compatibility is desired. This isn't necessarily a bad thing, but I'd say it's something to consider.

  • The proposers and reviewers of the Candidate Target must have a good-faith belief that the target will be proposed for inclusion in Rust in the future, and that the target will be capable of meeting the requirements for at least tier 3 even if it does not currently do so. The Candidate Target process exists to coordinate potential future targets, not to maintain targets out-of-tree indefinitely.

Relating to my previous point about fiesibility to implement in rustc, this seems to support that eventually inclusion in rustc itself is required. As mentioned, this may impose burden those who seek to implement a target in non-mainstream ways (IE. through llvm or gcc).

@chorman0773
Copy link

An additional question related to the last point. Would inclusion in upstream rustc via rustc_codegen_llvm/rustc_codegen_gcc require inclusion of the target in upstream llvm/gcc? If so, that may be an additional burden to people who are working off of the forks, but cannot, in good-faith, make any kind of reasonable guarantee that the modifications will eventually be included upstream.

@joshtriplett
Copy link
Member Author

I'm worried whether the Lang Team will have much to do other than say "yes we can add this target vs. no we cannot". If much of those details have been determined and implemented in a C compiler and code in the wild uses that C compiler, it would be highly difficult to change. Otherwise, people looking to add new rust targets would have to bring the consideration before significant work on a C implementation begins, and it could end up as T-lang now having to sign off on the ABI present in a C compiler. It also means it would be a significant burden if adding support to a target that already has a C compiler with which compatibility is desired. This isn't necessarily a bad thing, but I'd say it's something to consider.

The Candidate Target Policy is meant to allow for much earlier coordination precisely to help avert this kind of problem. However, we absolutely still need to acknowledge that sometimes a target will already exist elsewhere (most commonly in a popular C compiler, or for that matter potentially in more than one popular C compiler in incompatible forms...). In such a case, we would have to evaluate the tradeoffs there, as well as evaluating how much we need to support the target. We might choose to not support the target, or we might choose to match an existing ABI for interoperability at the risk of being incompatible with parts of the Rust ecosystem, or we might consider diverging on a detail of the ABI if the target would still be useful without it (e.g. if interoperability were still possible and just more difficult, or if there are multiple ABIs and we don't need to interoperate with all of them, or if the target is still sufficiently useful). We'll have to consider the details for the particular target and the particular ABI issue.

Some aspects of the ABI may be more flexible than others. We can likely deal with almost any function-call ABI (given that it'll be the extern "C" ABI rather than the Rust function call ABI). Other ABI considerations might cause larger difficulties. For instance, we're unlikely to ever support an architecture with 9-bit bytes, or comparably exotic size/alignment requirements.

Relating to my previous point about fiesibility to implement in rustc, this seems to support that eventually inclusion in rustc itself is required.

Yes, that's the intention. However, this doesn't necessarily mean that a target must be included in LLVM or GCC. It could be supported via cranelift, or via some new backend proposed for inclusion, or via out-of-tree changes in LLVM or GCC that will eventually get upstreamed.

The point of the Candidate Target Policy is to allow early coordination with Rust, to make sure that work being done out-of-tree aligns with Rust's target requirements (and naming), so that an implementation in Rust won't need to diverge from that out-of-tree work. If the developers of a target don't want to coordinate with Rust and have no intention of getting the target into Rust, then they don't get any value out of this policy.

Would inclusion in upstream rustc via rustc_codegen_llvm/rustc_codegen_gcc require inclusion of the target in upstream llvm/gcc? If so, that may be an additional burden to people who are working off of the forks, but cannot, in good-faith, make any kind of reasonable guarantee that the modifications will eventually be included upstream.

Nobody can guarantee that any particular modifications will be accepted upstream until they're actually accepted upstream. The ask here is to have a reasonable belief that they can be and will be. For instance, if you make changes in your own repository of LLVM or GCC to add a new target, and the target hasn't been merged yet, that's fine; you don't have to have some ironclad guarantee that the changes will go in. This requirement is talking about the case where you know those changes are done in a way upstream will find unacceptable, or where you know you have no intention of ever trying to upstream them.

@chorman0773
Copy link

Writeup of some discussion on zulip:
In addition to the current text, certain things should be permitted to be delegated in the approval of a Candidate Target to the target maintainer, or a body that handles the target, by the consent of the particular teams. As a non-exhaustive list, the following could be delegated to be added directly by the appropriate body:

  • Target Feature Names,
  • core::arch (possibly also std::os) intrinsic names, within the architecture's namespace,
  • target-specific directives for inline assembly, as well as register names and register class names, additional constraints, etc.
    The teams responsible for the delegation should assess all applicable circumstances before making such a delegation, and may place conditions on the delegation.

@wesleywiser
Copy link
Member

We discussed this RFC a bit in the compiler-team's steering meeting to review open RFCs. In general, we didn't have any major concerns about the content of the RFC but we're not really sure when we'd actually use this policy. We (the compiler team) typically do not have much interaction from target devs prior to a Tier 3 target proposal being submitted. By that time, there is usually already upstream support in GCC/LLVM and so much of the characteristics of the target have already been stabilized to some degree.

In addition to the current text, certain things should be permitted to be delegated in the approval of a Candidate Target to the target maintainer, or a body that handles the target, by the consent of the particular teams. As a non-exhaustive list, the following could be delegated to be added directly by the appropriate body:

  • Target Feature Names,
  • core::arch (possibly also std::os) intrinsic names, within the architecture's namespace,
  • target-specific directives for inline assembly, as well as register names and register class names, additional constraints, etc.

The teams responsible for the delegation should assess all applicable circumstances before making such a delegation, and may place conditions on the delegation.

Unless we're misunderstanding what exactly is meant by "delegation", this is essentially already our de-facto policy as we strongly encourage using the standard terminology for intrinsics, feature names, etc wherever possible unless there is a very strong reason not to. Making that policy official certainly seems reasonable to us!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-compiler Relevant to the compiler team, which will review and decide on the RFC. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants