1# Overview of the compiler23This chapter is about the overall process of compiling a program -- how everything fits together.45The Rust compiler is special in two ways: it does things to your code that6other compilers don't do (e.g. borrow-checking) and it has a lot of7unconventional implementation choices (e.g. queries).8We will talk about these in turn in this chapter, and in the rest of the guide, we will look at the9individual pieces in more detail.1011## What the compiler does to your code1213So first, let's look at what the compiler does to your code.14For now, we will avoid mentioning how the compiler implements these steps except as needed.1516### Invocation1718Compilation begins when a user writes a Rust source program in text and invokes19the `rustc` compiler on it.20The work that the compiler needs to perform is defined by command-line options.21For example, it is possible to enable nightly22features (`-Z` flags), perform `check`-only builds, or emit the LLVM23Intermediate Representation (`LLVM-IR`) rather than executable machine code.24The `rustc` executable call may be indirect through the use of `cargo`.2526Command line argument parsing occurs in the [`rustc_driver`].27This crate defines the compile configuration that is requested by the user and passes it28to the rest of the compilation process as a [`rustc_interface::Config`].2930### Lexing and parsing3132The raw Rust source text is analyzed by a low-level *lexer* located in [`rustc_lexer`].33At this stage, the source text is turned into a stream of34atomic source code units known as _tokens_.35 The `lexer` supports the Unicode character encoding.3637The token stream passes through a higher-level lexer located in38[`rustc_parse`] to prepare for the next stage of the compile process.39The [`Lexer`] `struct` is used at this stage to perform a set of validations40and turn strings into interned symbols (_interning_ is discussed later).41[String interning] is a way of storing only one immutable copy of each distinct string value.4243The lexer has a small interface and doesn't depend directly on the diagnostic44infrastructure in `rustc`.45Instead it provides diagnostics as plain data which46are emitted in [`rustc_parse::lexer`] as real diagnostics.47The `lexer` preserves full fidelity information for both IDEs and procedural macros48(sometimes referred to as "proc-macros").4950The *parser* [translates the token stream from the `lexer` into an Abstract Syntax51Tree (AST)][parser].52It uses a recursive descent (top-down) approach to syntax analysis.53The crate entry points for the `parser` are the54[`Parser::parse_crate_mod`][parse_crate_mod] and [`Parser::parse_mod`][parse_mod]55methods found in [`rustc_parse::parser::Parser`].56The external module parsing57entry point is [`rustc_expand::module::parse_external_mod`][parse_external_mod].58And the macro-`parser` entry point is [`Parser::parse_nonterminal`][parse_nonterminal].5960Parsing is performed with a set of [`parser`] utility methods including [`bump`],61[`check`], [`eat`], [`expect`], [`look_ahead`].6263Parsing is organized by semantic construct.64Separate `parse_*` methods can be found in the [`rustc_parse`][rustc_parse_parser_dir] directory.65The source file name follows the construct name.66For example, the following files are found in the `parser`:6768- [`expr.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/expr.rs)69- [`pat.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/pat.rs)70- [`ty.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/ty.rs)71- [`stmt.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_parse/src/parser/stmt.rs)7273This naming scheme is used across many compiler stages.74You will find either a file or directory with the same name across the parsing, lowering, type75checking, [Typed High-level Intermediate Representation (`THIR`)][thir] lowering, and76[Mid-level Intermediate Representation (`MIR`)][mir] building sources.7778Macro-expansion, `AST`-validation, name-resolution, and early linting also take79place during the lexing and parsing stage.8081The [`rustc_ast::ast`]::{[`Crate`], [`Expr`], [`Pat`], ...} `AST` nodes are82returned from the parser while the standard [`Diag`] API is used for error handling.83Generally Rust's compiler will try to recover from errors84by parsing a superset of Rust's grammar, while also emitting an error type.8586### `AST` lowering8788Next the `AST` is converted into [High-Level Intermediate Representation89(`HIR`)][hir], a more compiler-friendly representation of the `AST`.90This process is called "lowering" and involves a lot of desugaring (the expansion and91formalizing of shortened or abbreviated syntax constructs) of things like loops and `async fn`.9293We then use the `HIR` to do [*type inference*] (the process of automatic94detection of the type of an expression), [*trait solving*] (the process of95pairing up an impl with each reference to a `trait`), and [*type checking*].96Type checking is the process of converting the types found in the `HIR` ([`hir::Ty`]),97which represent what the user wrote, into the internal representation used by98the compiler ([`Ty<'tcx>`]).99It's called type checking because the information100is used to verify the type safety, correctness and coherence of the types used in the program.101102### `MIR` lowering103104The `HIR` is further lowered to `MIR`105(used for [borrow checking]) by constructing the `THIR` (an even more desugared `HIR` used for106pattern and exhaustiveness checking) to convert into `MIR`.107108We do [many optimizations on the MIR][mir-opt] because it is generic and that109improves later code generation and compilation speed.110It is easier to do some optimizations at `MIR` level than at `LLVM-IR` level.111For example LLVM doesn't seem112to be able to optimize the pattern the [`simplify_try`] `MIR`-opt looks for.113114Rust code is also [_monomorphized_] during code generation, which means making115copies of all the generic code with the type parameters replaced by concrete types.116To do this, we need to collect a list of what concrete types to generate code for.117This is called _monomorphization collection_ and it happens at the `MIR` level.118119[_monomorphized_]: https://en.wikipedia.org/wiki/Monomorphization120121### Code generation122123We then begin what is simply called _code generation_ or _codegen_.124The [code generation stage][codegen] is when higher-level representations of source are125turned into an executable binary.126Since `rustc` uses LLVM for code generation,127the first step is to convert the `MIR` to `LLVM-IR`.128This is where the `MIR` is actually monomorphized.129The `LLVM-IR` is passed to LLVM, which does a lot more130optimizations on it, emitting machine code which is basically assembly code131with additional low-level types and annotations added (e.g. an ELF object or132`WASM`).133The different libraries/binaries are then linked together to produce the final binary.134135[*trait solving*]: traits/resolution.md136[*type checking*]: hir-typeck/summary.md137[*type inference*]: type-inference.md138[`bump`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.bump139[`check`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.check140[`Crate`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Crate.html141[`diag`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html142[`eat`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.eat143[`expect`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.expect144[`Expr`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Expr.html145[`hir::Ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Ty.html146[`look_ahead`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.look_ahead147[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html148[`Pat`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/ast/struct.Pat.html149[`rustc_ast::ast`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_ast/index.html150[`rustc_driver`]: rustc-driver/intro.md151[`rustc_interface::Config`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html152[`rustc_lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html153[`rustc_parse::lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/index.html154[`rustc_parse::parser::Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html155[`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html156[`simplify_try`]: https://github.com/rust-lang/rust/pull/66282157[`Lexer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html158[`Ty<'tcx>`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html159[borrow checking]: borrow-check.md160[codegen]: backend/codegen.md161[hir]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html162[lex]: the-parser.md163[mir-opt]: mir/optimizations.md164[mir]: mir/index.md165[parse_crate_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_crate_mod166[parse_external_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/module/fn.parse_external_mod.html167[parse_mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_mod168[parse_nonterminal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.parse_nonterminal169[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html170[rustc_parse_parser_dir]: https://github.com/rust-lang/rust/tree/HEAD/compiler/rustc_parse/src/parser171[String interning]: https://en.wikipedia.org/wiki/String_interning172[thir]: ./thir.md173174## How it does it175176Now that we have a high-level view of what the compiler does to your code,177let's take a high-level view of _how_ it does all that stuff.178There are a lot of constraints and conflicting goals that the compiler needs to179satisfy/optimize for.180For example,181182- Compilation speed: how fast is it to compile a program?183 More/better compile-time analyses often means compilation is slower.184 - Also, we want to support incremental compilation, so we need to take that into account.185 How can we keep track of what work needs to be redone and186 what can be reused if the user modifies their program?187 - Also we can't store too much stuff in the incremental cache because188 it would take a long time to load from disk and it could take a lot189 of space on the user's system...190- Compiler memory usage: while compiling a program, we don't want to use more memory than we need.191- Program speed: how fast is your compiled program?192 More/better compile-time analyses often means the compiler can do better optimizations.193- Program size: how large is the compiled binary?194 Similar to the previous point.195- Compiler compilation speed: how long does it take to compile the compiler?196 This impacts contributors and compiler maintenance.197- Implementation complexity: building a compiler is one of the hardest198 things a person/group can do, and Rust is not a very simple language, so how199 do we make the compiler's code base manageable?200- Compiler correctness: the binaries produced by the compiler should do what201 the input programs says they do, and should continue to do so despite the202 tremendous amount of change constantly going on.203- Integration: a number of other tools need to use the compiler in204 various ways (e.g. `cargo`, `clippy`, `Miri`) that must be supported.205- Compiler stability: the compiler should not crash or fail ungracefully on the stable channel.206- Rust stability: the compiler must respect Rust's stability guarantees by not207 breaking programs that previously compiled despite the many changes that are208 always going on to its implementation.209- Limitations of other tools: `rustc` uses LLVM in its backend, and LLVM has some210 strengths we leverage and some aspects we need to work around.211212So, as you continue your journey through the rest of the guide, keep these things in mind.213They will often inform decisions that we make.214215### Intermediate representations216217As with most compilers, `rustc` uses some intermediate representations (IRs) to218facilitate computations.219In general, working directly with the source code is extremely inconvenient and error-prone.220Source code is designed to be human-friendly while at221the same time being unambiguous, but it's less convenient for doing something222like, say, type checking.223224Instead most compilers, including `rustc`, build some sort of IR out of the225source code which is easier to analyze.226`rustc` has a few IRs, each optimized for different purposes:227228- Token stream: the lexer produces a stream of tokens directly from the source code.229 This stream of tokens is easier for the parser to deal with than raw text.230- Abstract Syntax Tree (`AST`): the abstract syntax tree is built from the stream231 of tokens produced by the lexer.232 It represents pretty much exactly what the user wrote.233 It helps to do some syntactic sanity234 checking (e.g. checking that a type is expected where the user wrote one).235- High-level IR (HIR): This is a sort of desugared `AST`.236 It's still close to what the user wrote syntactically, but it includes some implicit things237 such as some elided lifetimes, etc. This IR is amenable to type checking.238- Typed `HIR` (THIR) _formerly High-level Abstract IR (HAIR)_: This is an239 intermediate between `HIR` and MIR.240 It is like the `HIR` but it is fully typed241 and a bit more desugared (e.g. method calls and implicit dereferences are242 made fully explicit).243 As a result, it is easier to lower to `MIR` from `THIR` than from HIR.244- Middle-level IR (`MIR`): This IR is basically a Control-Flow Graph (CFG).245 A CFG is a type of diagram that shows the basic blocks of a program and how control246 flow can go between them.247 Likewise, `MIR` also has a bunch of basic blocks with248 simple typed statements inside them (e.g. assignment, simple computations,249 etc) and control flow edges to other basic blocks (e.g., calls, dropping250 values).251 `MIR` is used for borrow checking and other252 important dataflow-based checks, such as checking for uninitialized values.253 It is also used for a series of optimizations and for constant evaluation (via `Miri`).254 Because `MIR` is still generic, we can do a lot of analyses here more255 efficiently than after monomorphization.256- `LLVM-IR`: This is the standard form of all input to the LLVM compiler.257 `LLVM-IR` is a sort of typed assembly language with lots of annotations.258 It's259 a standard format that is used by all compilers that use LLVM (e.g. the clang260 C compiler also outputs `LLVM-IR`).261 `LLVM-IR` is designed to be easy for other262 compilers to emit and also rich enough for LLVM to run a bunch of optimizations on it.263264One other thing to note is that many values in the compiler are _interned_.265This is a performance and memory optimization in which we allocate the values in266a special allocator called an _[arena]_.267Then, we pass around references to the values allocated in the arena.268This allows us to make269sure that identical values (e.g. types in your program) are only allocated once270and can be compared cheaply by comparing pointers.271Many of the intermediate representations are interned.272273[arena]: https://en.wikipedia.org/wiki/Region-based_memory_management274275### Queries276277The first big implementation choice is Rust's use of the _query_ system in its compiler.278The Rust compiler _is not_ organized as a series of passes over the code which execute sequentially.279The Rust compiler does this to make280incremental compilation possible -- that is, if the user makes a change to281their program and recompiles, we want to do as little redundant work as282possible to output the new binary.283284In `rustc`, all the major steps above are organized as a bunch of queries that call each other.285For example, there is a query to ask for the type of something286and another to ask for the optimized `MIR` of a function.287These queries can call each other and are all tracked through the query system.288The results of the queries are cached on disk so that the compiler can tell which queries' results289changed from the last compilation and only redo those.290This is how incremental compilation works.291292In principle, for the query-fied steps, we do each of the above for each item individually.293For example, we will take the `HIR` for a function and use queries294to ask for the `LLVM-IR` for that HIR.295This drives the generation of optimized296`MIR`, which drives the borrow checker, which drives the generation of `MIR`, and so on.297298... except that this is very over-simplified.299In fact, some queries are not300cached on disk, and some parts of the compiler have to run for all code anyway301for correctness even if the code is dead code (e.g. the borrow checker). For302example, [currently the `mir_borrowck` query is first executed on all functions303of a crate.][passes] Then the codegen backend invokes the304`collect_and_partition_mono_items` query, which first recursively requests the305`optimized_mir` for all reachable functions, which in turn runs `mir_borrowck`306for that function and then creates codegen units.307This kind of split will need308to remain to ensure that unreachable functions still have their errors emitted.309310[passes]: https://github.com/rust-lang/rust/blob/e69c7306e2be08939d95f14229e3f96566fb206c/compiler/rustc_interface/src/passes.rs#L791311312Moreover, the compiler wasn't originally built to use a query system; the query313system has been retrofitted into the compiler, so parts of it are not query-fied yet.314Also, LLVM isn't our code, so that isn't querified either.315The plan is to eventually query-fy all of the steps listed in the previous section,316but as of <!-- date-check --> November 2022, only the steps between `HIR` and317`LLVM-IR` are query-fied.318That is, lexing, parsing, name resolution, and macro319expansion are done all at once for the whole program.320321One other thing to mention here is the all-important "typing context",322[`TyCtxt`], which is a giant struct that is at the center of all things.323(Note that the name is mostly historic.324This is _not_ a "typing context" in the sense of `Γ` or `Δ` from type theory.325The name is retained because that's what the name of the struct is in the source code.) All326queries are defined as methods on the [`TyCtxt`] type, and the in-memory query327cache is stored there too.328In the code, there is usually a variable called `tcx` which is a handle on the typing context.329You will also see lifetimes with330the name `'tcx`, which means that something is tied to the lifetime of the331[`TyCtxt`] (usually it is stored or interned there).332333[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html334335For more information about queries in the compiler, see [the queries chapter][queries].336337[queries]: ./query.md338339### `ty::Ty`340341Types are really important in Rust, and they form the core of a lot of compiler analyses.342The main type (in the compiler) that represents types (in the user's343program) is [`rustc_middle::ty::Ty`][ty].344This is so important that we have a whole chapter345on [`ty::Ty`][ty], but for now, we just want to mention that it exists and is the way346`rustc` represents types!347348Also note that the [`rustc_middle::ty`] module defines the [`TyCtxt`] struct we mentioned before.349350[ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html351[`rustc_middle::ty`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/index.html352353### Parallelism354355Compiler performance is a problem that we would like to improve on (and are always working on).356One aspect of that is parallelizing `rustc` itself.357358Currently, there is only one part of rustc that is parallel by default:359[code generation](./parallel-rustc.md#Codegen).360361However, the rest of the compiler is still not yet parallel.362There have been lots of efforts spent on this, but it is generally a hard problem.363The current approach is to turn [`RefCell`]s into [`Mutex`]s -- that is, we364switch to thread-safe internal mutability.365However, there are ongoing366challenges with lock contention, maintaining query-system invariants under367concurrency, and the complexity of the code base.368One can try out the current work by enabling parallel compilation in `bootstrap.toml`.369It's still early days,370but there are already some promising performance improvements.371372[`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html373[`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html374375### Bootstrapping376377`rustc` itself is written in Rust.378So how do we compile the compiler? We use an older compiler to compile the newer compiler.379This is called [_bootstrapping_].380381Bootstrapping has a lot of interesting implications.382For example, it means that one of the major users of Rust is the Rust compiler, so we are383constantly testing our own software ("eating our own dogfood").384385For more details on bootstrapping, see [the bootstrapping section of the guide][rustc-bootstrap].386387[_bootstrapping_]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)388[rustc-bootstrap]: building/bootstrapping/intro.md389390<!--391# Unresolved Questions392393- Does LLVM ever do optimizations in debug builds?394- How do I explore phases of the compile process in my own sources (lexer,395 parser, HIR, etc)? - e.g., `cargo rustc -- -Z unpretty=hir-tree` allows you to396 view `HIR` representation397- What is the main source entry point for `X`?398- Where do phases diverge for cross-compilation to machine code across different platforms?399-->400401# References402403- Command line parsing404 - Guide: [The Rustc Driver and Interface](rustc-driver/intro.md)405 - Driver definition: [`rustc_driver`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/)406 - Main entry point: [`rustc_session::config::build_session_options`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/config/fn.build_session_options.html)407- Lexical Analysis: Lex the user program to a stream of tokens408 - Guide: [Lexing and Parsing](the-parser.md)409 - Lexer definition: [`rustc_lexer`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/index.html)410 - Main entry point: [`rustc_lexer::Cursor::advance_token`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lexer/struct.Cursor.html#method.advance_token)411- Parsing: Parse the stream of tokens to an Abstract Syntax Tree (AST)412 - Guide: [Lexing and Parsing](the-parser.md)413 - Guide: [Macro Expansion](macro-expansion.md)414 - Guide: [Name Resolution](name-resolution.md)415 - Parser definition: [`rustc_parse`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html)416 - Main entry points:417 - [Entry point for first file in crate](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.parse.html)418 - [Entry point for outline module parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/module/fn.parse_external_mod.html)419 - [Entry point for macro fragments][parse_nonterminal]420 - `AST` definition: [`rustc_ast`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html)421 - Feature gating: [Feature Gate Checking](feature-gate-check.md)422 - Early linting: **TODO**423- The High Level Intermediate Representation (HIR)424 - Guide: [The HIR](hir.md)425 - Guide: [Identifiers in the HIR](hir.md#identifiers-in-the-hir)426 - Guide: [The `HIR` Map](hir.md#the-hir-map)427 - Guide: [Lowering `AST` to `HIR`](./hir/lowering.md)428 - How to view `HIR` representation for your code `cargo rustc -- -Z unpretty=hir-tree`429 - Rustc `HIR` definition: [`rustc_hir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html)430 - Main entry point: **TODO**431 - Late linting: **TODO**432- Type Inference433 - Guide: [Type Inference](type-inference.md)434 - Guide: [The ty Module: Representing Types](ty.md) (semantics)435 - Main entry point (type inference): [`InferCtxtBuilder::enter`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxtBuilder.html#method.enter)436 - Main entry point (type checking bodies): [the `typeck` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.typeck)437 - These two functions can't be decoupled.438- The Mid Level Intermediate Representation (MIR)439 - Guide: [The `MIR` (Mid level IR)](mir/index.md)440 - Definition: [`rustc_middle/src/mir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/index.html)441 - Definition of sources that manipulates the MIR: [`rustc_mir_build`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/index.html), [`rustc_mir_dataflow`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_dataflow/index.html), [`rustc_mir_transform`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/index.html)442- The Borrow Checker443 - Guide: [MIR Borrow Check](borrow-check.md)444 - Definition: [`rustc_borrowck`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/index.html)445 - Main entry point: [`mir_borrowck` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/fn.mir_borrowck.html)446- `MIR` Optimizations447 - Guide: [MIR Optimizations](mir/optimizations.md)448 - Definition: [`rustc_mir_transform`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/index.html)449 - Main entry point: [`optimized_mir` query](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/fn.optimized_mir.html)450- Code Generation451 - Guide: [Code Generation](backend/codegen.md)452 - Generating Machine Code from `LLVM-IR` with LLVM - **TODO: reference?**453 - Main entry point: [`rustc_codegen_ssa::base::codegen_crate`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html)454 - This monomorphizes and produces `LLVM-IR` for one codegen unit.455 It then starts a background thread to run LLVM, which must be joined later.456 - Monomorphization happens lazily via [`FunctionCx::monomorphize`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/struct.FunctionCx.html#method.monomorphize) and [`rustc_codegen_ssa::base::codegen_instance `](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_instance.html)
Findings
✓ No findings reported for this file.