about summary refs log tree commit diff
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-12-05 07:38:34 -0800
committerWho? Me?! <mark-i-m@users.noreply.github.com>2018-12-07 15:43:59 -0600
commit82f6ee311ebe9fd4109ea45e22e899dc30c83c31 (patch)
tree9ad7b70b34fff66d0a256116f130dd98cb3ab177 /src/doc/rustc-dev-guide
parent284c0254b361adc1106b4d3ff4bc4a6c8271b5ad (diff)
downloadrust-82f6ee311ebe9fd4109ea45e22e899dc30c83c31.tar.gz
rust-82f6ee311ebe9fd4109ea45e22e899dc30c83c31.zip
Add some documentation about updating LLVM
Diffstat (limited to 'src/doc/rustc-dev-guide')
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md1
-rw-r--r--src/doc/rustc-dev-guide/src/codegen/updating-llvm.md149
2 files changed, 150 insertions, 0 deletions
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index efe963c3fcb..bfb112ce642 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -65,6 +65,7 @@
     - [miri const evaluator](./miri.md)
 - [Parameter Environments](./param_env.md)
 - [Code Generation](./codegen.md)
+  - [Updating LLVM](./codegen/updating-llvm.md)
 - [Emitting Diagnostics](./diag.md)
 
 ---
diff --git a/src/doc/rustc-dev-guide/src/codegen/updating-llvm.md b/src/doc/rustc-dev-guide/src/codegen/updating-llvm.md
new file mode 100644
index 00000000000..e29e041b2b7
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/codegen/updating-llvm.md
@@ -0,0 +1,149 @@
+# Updating LLVM
+
+The Rust compiler uses LLVM as its primary codegen backend today, and naturally
+we want to at least occasionally update this dependency! Currently we do not
+have a strict policy about when to update LLVM or what it can be updated to, but
+a few guidelines are applied:
+
+* We try to always support the latest released version of LLVM
+* We try to support the "last few" versions of LLVM (how many is changing over
+  time)
+* We allow moving to arbitrary commits during development.
+* Strongly prefer to upstream all patches to LLVM before including them in
+  rustc.
+
+This policy may change over time (or may actually start to exist as a formal
+policy!), but for now these are rough guidelines!
+
+## Why update LLVM?
+
+There are two primary reasons nowadays that we want to update LLVM in one way or
+another:
+
+* First, 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
+  they're merged upstream.
+
+* Second, a new feature may be avaiable in LLVM that we want to use in rustc,
+  but we don't want to wait for a full LLVM release to test it out.
+
+Each of these reasons has a different strategy for updating LLVM, and we'll go
+over both in detail here.
+
+## Bugfix Updates
+
+For updates of LLVM that typically just update a bug, we cherry-pick the bugfix
+to the branch we're already using. The steps for this are:
+
+1. Make sure the bugfix is in upstream LLVM.
+2. Identify the branch that rustc is currently using. The `src/llvm` submodule
+   is always pinned to a branch of the
+   [rust-lang/llvm](https://github.com/rust-lang/llvm) repository.
+3. Fork the rust-lang/llvm repository
+4. Check out the appropriate branch (typically named `rust-llvm-release-*`)
+5. Cherry-pick the upstream commit onto the branch
+6. Push this branch to your fork
+7. Send a Pull Request to rust-lang/llvm to the same branch as before
+8. Wait for the PR to be merged
+9. Send a PR to rust-lang/rust updating the `src/llvm` submodule with your bugfix
+10. Wait for PR to be merged
+
+The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back
+into the rust-lang/llvm branch that we're using, and getting it into the
+compiler is just updating the submodule via a PR!
+
+Example PRs look like:
+[#56313](https://github.com/rust-lang/rust/pull/56313)
+
+## Feature updates
+
+> Note that this is all information as applies to the current day in age. This
+> 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
+lot more work. This is where we can't reasonably cherry-pick commits backwards
+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 new branches in all repositories for this update. Branches should be
+   named `rust-llvm-release-X-Y-Z-vA` where `X.Y.Z` is the LLVM version and `A`
+   is just increasing based on if there's previous branches of this name. All
+   repositories here should be branched at the same time from the upstream LLVM
+   projects, we currently use https://github.com/llvm-mirror repositories. The
+   list of repositories that need a new branch are:
+
+   * rust-lang/llvm
+   * rust-lang/compiler-rt
+   * rust-lang/lld
+   * rust-lang-nursery/lldb
+   * rust-lang-nursery/clang
+
+2. Apply Rust-specific patches to LLVM repositories. All features and bugfixes
+   are upstream, but there's often some weird build-related patches that don't
+   make sense to upstream which we have on our repositories. These patches are
+   typically the latest patches on the branch. All repositories, except `clang`,
+   currently have Rust-specific patches.
+
+3. Update the `compiler-rt` submodule in the
+   `rust-lang-nursery/compiler-builtins` repository. Push this update to a
+   `rust-llvm-release-*` branch of the `compiler-builtins` repository.
+
+4. Prepare a commit to rust-lang/rust
+
+  * Update `src/llvm`
+  * Update `src/tools/lld`
+  * Update `src/tools/lldb`
+  * Update `src/tools/clang`
+  * Update `src/libcompiler_builtins
+  * Edit `src/rustllvm/llvm-rebuild-trigger` to update its contents
+
+5. Build your commit. Make sure you've committed the previous changes 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/tools/lld` - same for LLD
+   * `./x.py build` - build the rest of rustc
+
+   You'll likely need to update `src/rustllvm/*.cpp` 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.
+
+6. 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
+   sending this to bors! If you're low on resources you can send the PR as-is
+   now to bors, though, and it'll get tested anyway.
+
+   Ideally, build LLVM and test it on a few platforms:
+
+   * Linux
+   * OSX
+   * Windows
+
+   and afterwards run some docker containers that CI also does:
+
+   * `./src/ci/docker/run.sh wasm32-unknown`
+   * `./src/ci/docker/run.sh arm-android`
+   * `./src/ci/docker/run.sh dist-various-1`
+   * `./src/ci/docker/run.sh dist-various-2`
+   * `./src/ci/docker/run.sh armhf-gnu`
+
+7. Send a PR! Hopefully it's smooth sailing from here :).
+
+For prior art, previous LLVM updates look like
+[#55835](https://github.com/rust-lang/rust/pull/55835)
+[#47828](https://github.com/rust-lang/rust/pull/47828)
+
+### Caveats and gotchas
+
+Ideally the above instructions are pretty smooth, but here's some caveats to
+keep in mind while going through them:
+
+* LLVM bugs are hard to find, don't hesitate to ask for help! Bisection is
+  definitely your friend here (yes LLVM takes forever to build, yet bisection is
+  still your friend)
+* Updating LLDB has some Rust-specific patches currently that aren't upstream.
+  If you have difficulty @tromey can likely help out.
+* If you've got general questions, @alexcrichton can help you out.
+* Creating branches is a privileged operation on GitHub, so you'll need someone
+  with write access to create the branches for you most likely.