date-check: updating-llvm (#1424)
This commit is contained in:
parent
36e15ae1dd
commit
6f3d5e4b00
|
|
@ -19,18 +19,13 @@ policy!), but for now these are rough guidelines!
|
||||||
|
|
||||||
## Why update LLVM?
|
## Why update LLVM?
|
||||||
|
|
||||||
There are a few reasons nowadays that we want to update LLVM in one way or
|
There are two reasons we would want to update LLVM:
|
||||||
another:
|
|
||||||
|
|
||||||
* A bug could have been fixed! Often we find bugs in the compiler and fix
|
* A bug could have been fixed! Often we find bugs in the compiler and fix
|
||||||
them upstream in LLVM. We'll want to pull fixes back to the compiler itself as
|
them upstream in LLVM. We'll want to pull fixes back to the compiler itself as
|
||||||
they're merged upstream.
|
they're merged upstream.
|
||||||
|
|
||||||
* A new feature may be available in LLVM that we want to use in rustc,
|
* LLVM itself may have a new release.
|
||||||
but we don't want to wait for a full LLVM release to test it out.
|
|
||||||
|
|
||||||
* LLVM itself may have a new release and we'd like to update to this LLVM
|
|
||||||
release.
|
|
||||||
|
|
||||||
Each of these reasons has a different strategy for updating LLVM, and we'll go
|
Each of these reasons has a different strategy for updating LLVM, and we'll go
|
||||||
over them in detail here.
|
over them in detail here.
|
||||||
|
|
@ -57,59 +52,67 @@ the branch we're already using. The steps for this are:
|
||||||
src/llvm-project` typically.
|
src/llvm-project` typically.
|
||||||
10. Wait for PR to be merged
|
10. Wait for PR to be merged
|
||||||
|
|
||||||
The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back
|
An example PR:
|
||||||
into the rust-lang/llvm-project branch that we're using, and getting it into the
|
|
||||||
compiler is just updating the submodule via a PR!
|
|
||||||
|
|
||||||
Example PRs look like:
|
|
||||||
[#59089](https://github.com/rust-lang/rust/pull/59089)
|
[#59089](https://github.com/rust-lang/rust/pull/59089)
|
||||||
|
|
||||||
## Feature updates
|
## New LLVM Release Updates
|
||||||
|
|
||||||
> Note that this information is as of the time of this writing, <!--
|
<!-- date-check: Aug 2022 -->
|
||||||
date-check --> October 2021. The process for updating LLVM changes with
|
|
||||||
practically all LLVM updates, so this may be out of date!
|
|
||||||
|
|
||||||
Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a
|
Unlike bugfixes,
|
||||||
lot more work. This is where we can't reasonably cherry-pick commits backwards
|
updating to a new release of LLVM typically requires a lot more work.
|
||||||
so we need to do a full update. There's a lot of stuff to do here, so let's go
|
This is where we can't reasonably cherry-pick commits backwards,
|
||||||
through each in detail.
|
so we need to do a full update.
|
||||||
|
There's a lot of stuff to do here,
|
||||||
|
so let's go through each in detail.
|
||||||
|
|
||||||
1. Create a new branch in the [rust-lang/llvm-project repository]. This branch
|
1. LLVM announces that its latest release version has branched.
|
||||||
should be named `rustc/a.b-yyyy-mm-dd` where `a.b` is the current version
|
This will show up as a branch in the [llvm/llvm-project repository],
|
||||||
number of LLVM in-tree at the time of the branch and the remaining part is
|
typically named `release/$N.x`,
|
||||||
today's date. Move this branch to the commit in LLVM that you'd like, which
|
where `$N` is the version of LLVM that's being released.
|
||||||
for this is probably the current LLVM HEAD.
|
|
||||||
|
|
||||||
2. Apply Rust-specific patches to the llvm-project repository. All features and
|
1. Create a new branch in the [rust-lang/llvm-project repository]
|
||||||
bugfixes are upstream, but there's often some weird build-related patches
|
from this `release/$N.x` branch,
|
||||||
that don't make sense to upstream which we have on our repositories. These
|
and name it `rustc/a.b-yyyy-mm-dd`,
|
||||||
patches are around the latest patches in the rust-lang/llvm-project branch
|
where `a.b` is the current version number of LLVM in-tree
|
||||||
that rustc is currently using.
|
at the time of the branch,
|
||||||
|
and the remaining part is the current date.
|
||||||
|
|
||||||
3. Build the new LLVM in the `rust` repository. To do this you'll want to update
|
2. Apply Rust-specific patches to the llvm-project repository.
|
||||||
the `src/llvm-project` repository to your branch and the revision you've
|
All features and bugfixes are upstream,
|
||||||
created. It's also typically a good idea to update `.gitmodules` with the new
|
but there's often some weird build-related patches
|
||||||
branch name of the LLVM submodule. Make sure you've committed changes to
|
that don't make sense to upstream.
|
||||||
`src/llvm-project` to ensure submodule updates aren't reverted. Some commands
|
These patches are typically the latest patches in the
|
||||||
you should execute are:
|
rust-lang/llvm-project branch that rustc is currently using.
|
||||||
|
|
||||||
|
3. Build the new LLVM in the `rust` repository.
|
||||||
|
To do this,
|
||||||
|
you'll want to update the `src/llvm-project` repository to your branch,
|
||||||
|
and the revision you've created.
|
||||||
|
It's also typically a good idea to update `.gitmodules` with the new
|
||||||
|
branch name of the LLVM submodule.
|
||||||
|
Make sure you've committed changes to
|
||||||
|
`src/llvm-project` to ensure submodule updates aren't reverted.
|
||||||
|
Some commands you should execute are:
|
||||||
|
|
||||||
* `./x.py build src/llvm` - test that LLVM still builds
|
* `./x.py build src/llvm` - test that LLVM still builds
|
||||||
* `./x.py build src/tools/lld` - same for LLD
|
* `./x.py build src/tools/lld` - same for LLD
|
||||||
* `./x.py build` - build the rest of rustc
|
* `./x.py build` - build the rest of rustc
|
||||||
|
|
||||||
You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] to compile
|
You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`]
|
||||||
with updated LLVM bindings. Note that you should use `#ifdef` and such to ensure
|
to compile with updated LLVM bindings.
|
||||||
|
Note that you should use `#ifdef` and such to ensure
|
||||||
that the bindings still compile on older LLVM versions.
|
that the bindings still compile on older LLVM versions.
|
||||||
|
|
||||||
Note that `profile = "compiler"` and other defaults set by `./x.py setup`
|
Note that `profile = "compiler"` and other defaults set by `./x.py setup`
|
||||||
download LLVM from CI instead of building it from source. You should
|
download LLVM from CI instead of building it from source.
|
||||||
disable this temporarily to make sure your changes are being used, by setting
|
You should disable this temporarily to make sure your changes are being used.
|
||||||
|
This is done by having the following setting in `config.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[llvm]
|
[llvm]
|
||||||
download-ci-llvm = false
|
download-ci-llvm = false
|
||||||
```
|
```
|
||||||
in config.toml.
|
|
||||||
|
|
||||||
4. Test for regressions across other platforms. LLVM often has at least one bug
|
4. Test for regressions across other platforms. LLVM often has at least one bug
|
||||||
for non-tier-1 architectures, so it's good to do some more testing before
|
for non-tier-1 architectures, so it's good to do some more testing before
|
||||||
|
|
@ -122,7 +125,7 @@ through each in detail.
|
||||||
* macOS
|
* macOS
|
||||||
* Windows
|
* Windows
|
||||||
|
|
||||||
and afterwards run some docker containers that CI also does:
|
Afterwards, run some docker containers that CI also does:
|
||||||
|
|
||||||
* `./src/ci/docker/run.sh wasm32`
|
* `./src/ci/docker/run.sh wasm32`
|
||||||
* `./src/ci/docker/run.sh arm-android`
|
* `./src/ci/docker/run.sh arm-android`
|
||||||
|
|
@ -135,16 +138,39 @@ through each in detail.
|
||||||
and then you can send a PR to `rust-lang/rust`. You'll change at least
|
and then you can send a PR to `rust-lang/rust`. You'll change at least
|
||||||
`src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
|
`src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
|
||||||
|
|
||||||
For prior art, previous LLVM updates look like
|
> For prior art, here are some previous LLVM updates:
|
||||||
[#62474](https://github.com/rust-lang/rust/pull/62474)
|
> - [LLVM 11](https://github.com/rust-lang/rust/pull/73526)
|
||||||
[#62592](https://github.com/rust-lang/rust/pull/62592)
|
> - [LLVM 12](https://github.com/rust-lang/rust/pull/81451)
|
||||||
[#67759](https://github.com/rust-lang/rust/pull/67759)
|
> - [LLVM 13](https://github.com/rust-lang/rust/pull/87570)
|
||||||
[#73526](https://github.com/rust-lang/rust/pull/73526)
|
> - [LLVM 14](https://github.com/rust-lang/rust/pull/93577)
|
||||||
[#81451](https://github.com/rust-lang/rust/pull/81451). Note that sometimes it's
|
> - [LLVM 15](https://github.com/rust-lang/rust/pull/99464)
|
||||||
easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating
|
|
||||||
`src/llvm-project`. This way while you're working through LLVM issues others
|
Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR
|
||||||
interested in trying out the new LLVM can benefit from work you've done to
|
before actually updating `src/llvm-project`.
|
||||||
update the C++ bindings.
|
This way,
|
||||||
|
while you're working through LLVM issues,
|
||||||
|
others interested in trying out the new LLVM can benefit from work you've done
|
||||||
|
to update the C++ bindings.
|
||||||
|
|
||||||
|
3. Over the next few months,
|
||||||
|
LLVM will continually push commits to its `release/a.b` branch.
|
||||||
|
We will often want to have those bug fixes as well.
|
||||||
|
The merge process for that is to use `git merge` itself to merge LLVM's
|
||||||
|
`release/a.b` branch with the branch created in step 2.
|
||||||
|
This is typically
|
||||||
|
done multiple times when necessary while LLVM's release branch is baking.
|
||||||
|
|
||||||
|
4. LLVM then announces the release of version `a.b`.
|
||||||
|
|
||||||
|
5. After LLVM's official release,
|
||||||
|
we follow the process of creating a new branch on the
|
||||||
|
rust-lang/llvm-project repository again,
|
||||||
|
this time with a new date.
|
||||||
|
It is only then that the PR to update Rust to use that version is merged.
|
||||||
|
|
||||||
|
The commit history of `rust-lang/llvm-project`
|
||||||
|
should look much cleaner as a `git rebase` is done,
|
||||||
|
where just a few Rust-specific commits are stacked on top of stock LLVM's release branch.
|
||||||
|
|
||||||
### Caveats and gotchas
|
### Caveats and gotchas
|
||||||
|
|
||||||
|
|
@ -158,35 +184,6 @@ keep in mind while going through them:
|
||||||
* Creating branches is a privileged operation on GitHub, so you'll need someone
|
* Creating branches is a privileged operation on GitHub, so you'll need someone
|
||||||
with write access to create the branches for you most likely.
|
with write access to create the branches for you most likely.
|
||||||
|
|
||||||
## New LLVM Release Updates
|
|
||||||
|
|
||||||
Updating to a new release of LLVM is very similar to the "feature updates"
|
|
||||||
section above. The release process for LLVM is often months-long though and we
|
|
||||||
like to ensure compatibility ASAP. The main tweaks to the "feature updates"
|
|
||||||
section above is generally around branch naming. The sequence of events
|
|
||||||
typically looks like:
|
|
||||||
|
|
||||||
1. LLVM announces that its latest release version has branched. This will show
|
|
||||||
up as a branch in the [llvm/llvm-project repository] typically named
|
|
||||||
`release/$N.x` where `$N` is the version of LLVM that's being released.
|
|
||||||
|
|
||||||
2. We then follow the "feature updates" section above to create a new branch of
|
|
||||||
LLVM in our rust-lang/llvm-project repository. This follows the same naming
|
|
||||||
convention of branches as usual, except that `a.b` is the new version. This
|
|
||||||
update is eventually landed in the rust-lang/rust repository.
|
|
||||||
|
|
||||||
3. Over the next few months, LLVM will continually push commits to its
|
|
||||||
`release/a.b` branch. Often those are bug fixes we'd like to have as well.
|
|
||||||
The merge process for that is to use `git merge` itself to merge LLVM's
|
|
||||||
`release/a.b` branch with the branch created in step 2. This is typically
|
|
||||||
done multiple times when necessary while LLVM's release branch is baking.
|
|
||||||
|
|
||||||
4. LLVM then announces the release of version `a.b`.
|
|
||||||
|
|
||||||
5. After LLVM's official release, we follow the "feature update" section again
|
|
||||||
to create a new branch in the rust-lang/llvm-project repository, this time
|
|
||||||
with a new date. The commit history should look much cleaner as just a few
|
|
||||||
Rust-specific commits stacked on top of stock LLVM's release branch.
|
|
||||||
|
|
||||||
[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
|
[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
|
||||||
[llvm/llvm-project repository]: https://github.com/llvm/llvm-project
|
[llvm/llvm-project repository]: https://github.com/llvm/llvm-project
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue