| # Code generation |
| |
| Code generation (or "codegen") is the part of the compiler |
| that actually generates an executable binary. |
| Usually, rustc uses LLVM for code generation, |
| but there is also support for [Cranelift] and [GCC]. |
| The key is that rustc doesn't implement codegen itself. |
| It's worth noting, though, that in the Rust source code, |
| many parts of the backend have `codegen` in their names (there are no hard boundaries). |
| |
| [Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/main/cranelift |
| [GCC]: https://github.com/rust-lang/rustc_codegen_gcc |
| |
| > NOTE: If you are looking for hints on how to debug code generation bugs, |
| > please see [this section of the debugging chapter][debugging]. |
| |
| [debugging]: ./debugging.md |
| |
| ## What is LLVM? |
| |
| [LLVM](https://llvm.org) is "a collection of modular and reusable compiler and |
| toolchain technologies". |
| In particular, the LLVM project contains a pluggable |
| compiler backend (also called "LLVM"), which is used by many compiler projects, |
| including the `clang` C compiler and our beloved `rustc`. |
| |
| LLVM takes input in the form of LLVM IR. |
| It is basically assembly code with additional low-level types and annotations added. |
| These annotations are helpful for doing optimizations on the LLVM IR and outputted machine code. |
| The end result of all this is (at long last) something executable (e.g. an ELF object, |
| an EXE, or wasm). |
| |
| There are a few benefits to using LLVM: |
| |
| - We don't have to write a whole compiler backend. |
| This reduces implementation and maintenance burden. |
| - We benefit from the large suite of advanced optimizations that the LLVM |
| project has been collecting. |
| - We can automatically compile Rust to any of the platforms for which LLVM has support. |
| For example, as soon as LLVM added support for wasm, voila! |
| rustc, clang, and a bunch of other languages were able to compile to wasm! |
| (Well, there was some extra stuff to be done, but we were 90% there anyway). |
| - We and other compiler projects benefit from each other. |
| For example, when the [Spectre and Meltdown security vulnerabilities][spectre] were discovered, |
| only LLVM needed to be patched. |
| |
| [spectre]: https://meltdownattack.com/ |
| |
| ## Running LLVM, linking, and metadata generation |
| |
| Once LLVM IR for all of the functions and statics, etc is built, it is time to |
| start running LLVM and its optimization passes. |
| LLVM IR is grouped into "modules". |
| Multiple "modules" can be codegened at the same time to aid in multi-core utilization. |
| These "modules" are what we refer to as _codegen units_. |
| These units were established way back during monomorphization collection phase. |
| |
| Once LLVM produces objects from these modules, these objects are passed to the |
| linker along with, optionally, the metadata object and an archive or an executable is produced. |
| |
| It is not necessarily the codegen phase described above that runs the optimizations. |
| With certain kinds of LTO, the optimization might happen during linking time instead. |
| It is also possible for some optimizations to happen |
| before objects are passed on to the linker and some to happen during the linking. |
| |
| This all happens towards the very end of compilation. |
| The code for this can be found in [`rustc_codegen_ssa::back`][ssaback] and |
| [`rustc_codegen_llvm::back`][llvmback]. |
| Sadly, this piece of code is not really well-separated into LLVM-dependent code; |
| the [`rustc_codegen_ssa`][ssa] contains a fair amount of code specific to the LLVM backend. |
| |
| Once these components are done with their work you end up with a number of |
| files in your filesystem corresponding to the outputs you have requested. |
| |
| [ssa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html |
| [ssaback]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/back/index.html |
| [llvmback]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/back/index.html |