Optimize catch_unwind to match C++ try/catch This refactors the implementation of catching unwinds to allow LLVM to inline the "try" closure directly into the happy path, avoiding indirection. This means that the catch_unwind implementation is (after this PR) zero-cost unless a panic is thrown. https://rust.godbolt.org/z/cZcUSB is an example of the current codegen in a simple case. Notably, the codegen is *exactly the same* if `-Cpanic=abort` is passed, which is clearly not great. This PR, on the other hand, generates the following assembly: ```asm # -Cpanic=unwind: push rbx mov ebx,0x2a call QWORD PTR [rip+0x1c53c] # <happy> mov eax,ebx pop rbx ret mov rdi,rax call QWORD PTR [rip+0x1c537] # cleanup function call call QWORD PTR [rip+0x1c539] # <unfortunate> mov ebx,0xd mov eax,ebx pop rbx ret # -Cpanic=abort: push rax call QWORD PTR [rip+0x20a1] # <happy> mov eax,0x2a pop rcx ret ``` Fixes #64224, and resolves #64222. |
||
|---|---|---|
| .. | ||
| back | ||
| debuginfo | ||
| llvm | ||
| abi.rs | ||
| allocator.rs | ||
| asm.rs | ||
| attributes.rs | ||
| base.rs | ||
| build.rs | ||
| builder.rs | ||
| callee.rs | ||
| Cargo.toml | ||
| common.rs | ||
| consts.rs | ||
| context.rs | ||
| declare.rs | ||
| intrinsic.rs | ||
| lib.rs | ||
| llvm_util.rs | ||
| metadata.rs | ||
| mono_item.rs | ||
| README.md | ||
| type_.rs | ||
| type_of.rs | ||
| va_arg.rs | ||
| value.rs | ||
The codegen crate contains the code to convert from MIR into LLVM IR,
and then from LLVM IR into machine code. In general it contains code
that runs towards the end of the compilation process.
For more information about how codegen works, see the rustc dev guide.