| # Lowering MIR to a Codegen IR |
| |
| Now that we have a list of symbols to generate from the collector, we need to |
| generate some sort of codegen IR. In this chapter, we will assume LLVM IR, |
| since that's what rustc usually uses. The actual monomorphization is performed |
| as we go, while we do the translation. |
| |
| Recall that the backend is started by |
| [`rustc_codegen_ssa::base::codegen_crate`][codegen1]. Eventually, this reaches |
| [`rustc_codegen_ssa::mir::codegen_mir`][codegen2], which does the lowering from |
| MIR to LLVM IR. |
| |
| [codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html |
| [codegen2]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/fn.codegen_mir.html |
| |
| The code is split into modules which handle particular MIR primitives: |
| |
| - [`rustc_codegen_ssa::mir::block`][mirblk] will deal with translating |
| blocks and their terminators. The most complicated and also the most |
| interesting thing this module does is generating code for function calls, |
| including the necessary unwinding handling IR. |
| - [`rustc_codegen_ssa::mir::statement`][mirst] translates MIR statements. |
| - [`rustc_codegen_ssa::mir::operand`][mirop] translates MIR operands. |
| - [`rustc_codegen_ssa::mir::place`][mirpl] translates MIR place references. |
| - [`rustc_codegen_ssa::mir::rvalue`][mirrv] translates MIR r-values. |
| |
| [mirblk]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/block/index.html |
| [mirst]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/statement/index.html |
| [mirop]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/operand/index.html |
| [mirpl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/place/index.html |
| [mirrv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/rvalue/index.html |
| |
| Before a function is translated a number of simple and primitive analysis |
| passes will run to help us generate simpler and more efficient LLVM IR. An |
| example of such an analysis pass would be figuring out which variables are |
| SSA-like, so that we can translate them to SSA directly rather than relying on |
| LLVM's `mem2reg` for those variables. The analysis can be found in |
| [`rustc_codegen_ssa::mir::analyze`][mirana]. |
| |
| [mirana]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/analyze/index.html |
| |
| Usually a single MIR basic block will map to a LLVM basic block, with very few |
| exceptions: intrinsic or function calls and less basic MIR statements like |
| `assert` can result in multiple basic blocks. This is a perfect lede into the |
| non-portable LLVM-specific part of the code generation. Intrinsic generation is |
| fairly easy to understand as it involves very few abstraction levels in between |
| and can be found in [`rustc_codegen_llvm::intrinsic`][llvmint]. |
| |
| [llvmint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/intrinsic/index.html |
| |
| Everything else will use the [builder interface][builder]. This is the code that gets |
| called in the [`rustc_codegen_ssa::mir::*`][ssamir] modules discussed above. |
| |
| [builder]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/builder/index.html |
| [ssamir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/index.html |
| |
| > TODO: discuss how constants are generated |