]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-dev-guide/src/backend/updating-llvm.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / src / backend / updating-llvm.md
1 # Updating LLVM
2
3 <!-- toc -->
4
5 The Rust compiler uses LLVM as its primary codegen backend today, and naturally
6 we want to at least occasionally update this dependency! Currently we do not
7 have a strict policy about when to update LLVM or what it can be updated to, but
8 a few guidelines are applied:
9
10 * We try to always support the latest released version of LLVM
11 * We try to support the "last few" versions of LLVM (how many is changing over
12 time)
13 * We allow moving to arbitrary commits during development.
14 * Strongly prefer to upstream all patches to LLVM before including them in
15 rustc.
16
17 This policy may change over time (or may actually start to exist as a formal
18 policy!), but for now these are rough guidelines!
19
20 ## Why update LLVM?
21
22 There are a few reasons nowadays that we want to update LLVM in one way or
23 another:
24
25 * A bug could have been fixed! Often we find bugs in the compiler and fix
26 them upstream in LLVM. We'll want to pull fixes back to the compiler itself as
27 they're merged upstream.
28
29 * A new feature may be available in LLVM that we want to use in rustc,
30 but we don't want to wait for a full LLVM release to test it out.
31
32 * LLVM itself may have a new release and we'd like to update to this LLVM
33 release.
34
35 Each of these reasons has a different strategy for updating LLVM, and we'll go
36 over them in detail here.
37
38 ## Bugfix Updates
39
40 For updates of LLVM that are to fix a small bug, we cherry-pick the bugfix to
41 the branch we're already using. The steps for this are:
42
43 1. Make sure the bugfix is in upstream LLVM.
44 2. Identify the branch that rustc is currently using. The `src/llvm-project`
45 submodule is always pinned to a branch of the
46 [rust-lang/llvm-project](https://github.com/rust-lang/llvm-project) repository.
47 3. Fork the rust-lang/llvm-project repository
48 4. Check out the appropriate branch (typically named `rustc/a.b-yyyy-mm-dd`)
49 5. Cherry-pick the upstream commit onto the branch
50 6. Push this branch to your fork
51 7. Send a Pull Request to rust-lang/llvm-project to the same branch as before.
52 Be sure to reference the Rust and/or LLVM issue that you're fixing in the PR
53 description.
54 8. Wait for the PR to be merged
55 9. Send a PR to rust-lang/rust updating the `src/llvm-project` submodule with
56 your bugfix. This can be done locally with `git submodule update --remote
57 src/llvm-project` typically.
58 10. Wait for PR to be merged
59
60 The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back
61 into the rust-lang/llvm-project branch that we're using, and getting it into the
62 compiler is just updating the submodule via a PR!
63
64 Example PRs look like:
65 [#59089](https://github.com/rust-lang/rust/pull/59089)
66
67 ## Feature updates
68
69 > Note that this information is as of the time of this writing <!-- date:
70 2018-12 --> (December 2018). The process for updating LLVM changes with
71 practically all LLVM updates, so this may be out of date!
72
73 Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a
74 lot more work. This is where we can't reasonably cherry-pick commits backwards
75 so we need to do a full update. There's a lot of stuff to do here, so let's go
76 through each in detail.
77
78 1. Create a new branch in the rust-lang/llvm-project repository. This branch
79 should be named `rustc/a.b-yyyy-mm-dd` where `a.b` is the current version
80 number of LLVM in-tree at the time of the branch and the remaining part is
81 today's date. Move this branch to the commit in LLVM that you'd like, which
82 for this is probably the current LLVM HEAD.
83
84 2. Apply Rust-specific patches to the llvm-project repository. All features and
85 bugfixes are upstream, but there's often some weird build-related patches
86 that don't make sense to upstream which we have on our repositories. These
87 patches are around the latest patches in the rust-lang/llvm-project branch
88 that rustc is currently using.
89
90 3. Build the new LLVM in the `rust` repository. To do this you'll want to update
91 the `src/llvm-project` repository to your branch and the revision you've
92 created. It's also typically a good idea to update `.gitmodules` with the new
93 branch name of the LLVM submodule. Make sure you've committed changes to
94 `src/llvm-project` to ensure submodule updates aren't reverted. Some commands
95 you should execute are:
96
97 * `./x.py build src/llvm` - test that LLVM still builds
98 * `./x.py build src/tools/lld` - same for LLD
99 * `./x.py build` - build the rest of rustc
100
101 You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] to compile
102 with updated LLVM bindings. Note that you should use `#ifdef` and such to ensure
103 that the bindings still compile on older LLVM versions.
104
105 Note that `profile = "compiler"` and other defaults set by `x.py setup`
106 download LLVM from CI instead of building it from source. You should
107 disable this temporarily to make sure your changes are being used, by setting
108 ```toml
109 [llvm]
110 download-ci-llvm = false
111 ```
112 in config.toml.
113
114 4. Test for regressions across other platforms. LLVM often has at least one bug
115 for non-tier-1 architectures, so it's good to do some more testing before
116 sending this to bors! If you're low on resources you can send the PR as-is
117 now to bors, though, and it'll get tested anyway.
118
119 Ideally, build LLVM and test it on a few platforms:
120
121 * Linux
122 * OSX
123 * Windows
124
125 and afterwards run some docker containers that CI also does:
126
127 * `./src/ci/docker/run.sh wasm32-unknown`
128 * `./src/ci/docker/run.sh arm-android`
129 * `./src/ci/docker/run.sh dist-various-1`
130 * `./src/ci/docker/run.sh dist-various-2`
131 * `./src/ci/docker/run.sh armhf-gnu`
132
133 5. Prepare a PR to `rust-lang/rust`. Work with maintainers of
134 `rust-lang/llvm-project` to get your commit in a branch of that repository,
135 and then you can send a PR to `rust-lang/rust`. You'll change at least
136 `src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
137
138 For prior art, previous LLVM updates look like
139 [#55835](https://github.com/rust-lang/rust/pull/55835)
140 [#47828](https://github.com/rust-lang/rust/pull/47828)
141 [#62474](https://github.com/rust-lang/rust/pull/62474)
142 [#62592](https://github.com/rust-lang/rust/pull/62592). Note that sometimes it's
143 easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating
144 `src/llvm-project`. This way while you're working through LLVM issues others
145 interested in trying out the new LLVM can benefit from work you've done to
146 update the C++ bindings.
147
148 [`llvm-wrapper`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_llvm/llvm-wrapper
149
150 ### Caveats and gotchas
151
152 Ideally the above instructions are pretty smooth, but here's some caveats to
153 keep in mind while going through them:
154
155 * LLVM bugs are hard to find, don't hesitate to ask for help! Bisection is
156 definitely your friend here (yes LLVM takes forever to build, yet bisection is
157 still your friend)
158 * If you've got general questions, @alexcrichton can help you out.
159 * Creating branches is a privileged operation on GitHub, so you'll need someone
160 with write access to create the branches for you most likely.
161
162 ## New LLVM Release Updates
163
164 Updating to a new release of LLVM is very similar to the "feature updates"
165 section above. The release process for LLVM is often months-long though and we
166 like to ensure compatibility ASAP. The main tweaks to the "feature updates"
167 section above is generally around branch naming. The sequence of events
168 typically looks like:
169
170 1. LLVM announces that its latest release version has branched. This will show
171 up as a branch in https://github.com/llvm/llvm-project typically named
172 `release/$N.x` where `$N` is the version of LLVM that's being released.
173
174 2. We then follow the "feature updates" section above to create a new branch of
175 LLVM in our rust-lang/llvm-project repository. This follows the same naming
176 convention of branches as usual, except that `a.b` is the new version. This
177 update is eventually landed in the rust-lang/rust repository.
178
179 3. Over the next few months, LLVM will continually push commits to its
180 `release/a.b` branch. Often those are bug fixes we'd like to have as well.
181 The merge process for that is to use `git merge` itself to merge LLVM's
182 `release/a.b` branch with the branch created in step 2. This is typically
183 done multiple times when necessary while LLVM's release branch is baking.
184
185 4. LLVM then announces the release of version `a.b`.
186
187 5. After LLVM's official release, we follow the "feature update" section again
188 to create a new branch in the rust-lang/llvm-project repository, this time
189 with a new date. The commit history should look much cleaner as just a few
190 Rust-specific commits stacked on top of stock LLVM's release branch.