]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | # Lowering MIR to a Codegen IR |
2 | ||
3 | Now that we have a list of symbols to generate from the collector, we need to | |
4 | generate some sort of codegen IR. In this chapter, we will assume LLVM IR, | |
5 | since that's what rustc usually uses. The actual monomorphization is performed | |
6 | as we go, while we do the translation. | |
7 | ||
8 | Recall that the backend is started by | |
9 | [`rustc_codegen_ssa::base::codegen_crate`][codegen1]. Eventually, this reaches | |
10 | [`rustc_codegen_ssa::mir::codegen_mir`][codegen2], which does the lowering from | |
11 | MIR to LLVM IR. | |
12 | ||
13 | [codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html | |
14 | [codegen2]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/fn.codegen_mir.html | |
15 | ||
16 | The code is split into modules which handle particular MIR primitives: | |
17 | ||
6a06907d | 18 | - [`rustc_codegen_ssa::mir::block`][mirblk] will deal with translating |
ba9703b0 XL |
19 | blocks and their terminators. The most complicated and also the most |
20 | interesting thing this module does is generating code for function calls, | |
21 | including the necessary unwinding handling IR. | |
6a06907d XL |
22 | - [`rustc_codegen_ssa::mir::statement`][mirst] translates MIR statements. |
23 | - [`rustc_codegen_ssa::mir::operand`][mirop] translates MIR operands. | |
24 | - [`rustc_codegen_ssa::mir::place`][mirpl] translates MIR place references. | |
25 | - [`rustc_codegen_ssa::mir::rvalue`][mirrv] translates MIR r-values. | |
ba9703b0 XL |
26 | |
27 | [mirblk]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/block/index.html | |
28 | [mirst]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/statement/index.html | |
29 | [mirop]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/operand/index.html | |
30 | [mirpl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/place/index.html | |
31 | [mirrv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/rvalue/index.html | |
32 | ||
33 | Before a function is translated a number of simple and primitive analysis | |
34 | passes will run to help us generate simpler and more efficient LLVM IR. An | |
35 | example of such an analysis pass would be figuring out which variables are | |
36 | SSA-like, so that we can translate them to SSA directly rather than relying on | |
37 | LLVM's `mem2reg` for those variables. The analysis can be found in | |
38 | [`rustc_codegen_ssa::mir::analyze`][mirana]. | |
39 | ||
40 | [mirana]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/analyze/index.html | |
6a06907d | 41 | |
ba9703b0 XL |
42 | Usually a single MIR basic block will map to a LLVM basic block, with very few |
43 | exceptions: intrinsic or function calls and less basic MIR statements like | |
44 | `assert` can result in multiple basic blocks. This is a perfect lede into the | |
45 | non-portable LLVM-specific part of the code generation. Intrinsic generation is | |
46 | fairly easy to understand as it involves very few abstraction levels in between | |
47 | and can be found in [`rustc_codegen_llvm::intrinsic`][llvmint]. | |
48 | ||
49 | [llvmint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/intrinsic/index.html | |
50 | ||
51 | Everything else will use the [builder interface][builder]. This is the code that gets | |
6a06907d | 52 | called in the [`rustc_codegen_ssa::mir::*`][ssamir] modules discussed above. |
ba9703b0 XL |
53 | |
54 | [builder]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/builder/index.html | |
55 | [ssamir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/index.html | |
56 | ||
57 | > TODO: discuss how constants are generated |