]> git.lizzy.rs Git - rust.git/commit
Auto merge of #67502 - Mark-Simulacrum:opt-catch, r=Mark-Simulacrum
authorbors <bors@rust-lang.org>
Fri, 13 Mar 2020 22:43:06 +0000 (22:43 +0000)
committerbors <bors@rust-lang.org>
Fri, 13 Mar 2020 22:43:06 +0000 (22:43 +0000)
commitbe055d96c4c223a5ad49a0181f0b43bc46781708
tree72cda37978123f3dff36d9c24f599837097df9db
parent1572c433eed495d0ade41511ae106b180e02851d
parent9f3679fe4485aa4be4a0de9abc8aca938c60db36
Auto merge of #67502 - Mark-Simulacrum:opt-catch, r=Mark-Simulacrum

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.
src/libcore/intrinsics.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_ssa/back/link.rs
src/librustc_codegen_ssa/mir/block.rs
src/librustc_span/symbol.rs
src/librustc_target/spec/mod.rs
src/librustc_typeck/check/intrinsic.rs
src/tools/tidy/src/pal.rs