diff options
| author | bors <bors@rust-lang.org> | 2022-10-31 00:40:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-10-31 00:40:32 +0000 |
| commit | d726c8467c06088d5d4488edf6b015ec9698c1ea (patch) | |
| tree | 1df090647efa2e06275cc8060df4774f9affdea7 /compiler/rustc_codegen_llvm/src/asm.rs | |
| parent | 77e57db384aca99444c3b5f6a9c86bc58a804d89 (diff) | |
| parent | 003a3f8cd3ea4594e2c2bc89c05562a202868ce0 (diff) | |
| download | rust-d726c8467c06088d5d4488edf6b015ec9698c1ea.tar.gz rust-d726c8467c06088d5d4488edf6b015ec9698c1ea.zip | |
Auto merge of #103331 - nnethercote:convert-switch-to-br, r=scottmcm
Use `br` instead of `switch` in more cases.
`codegen_switchint_terminator` already uses `br` instead of `switch` when there is one normal target plus the `otherwise` target. But there's another common case with two normal targets and an `otherwise` target that points to an empty unreachable BB. This comes up a lot when switching on the tags of enums that use niches.
The pattern looks like this:
```
bb1: ; preds = %bb6
%3 = load i8, ptr %_2, align 1, !range !9, !noundef !4
%4 = sub i8 %3, 2
%5 = icmp eq i8 %4, 0
%_6 = select i1 %5, i64 0, i64 1
switch i64 %_6, label %bb3 [
i64 0, label %bb4
i64 1, label %bb2
]
bb3: ; preds = %bb1
unreachable
```
This commit adds code to convert the `switch` to a `br`:
```
bb1: ; preds = %bb6
%3 = load i8, ptr %_2, align 1, !range !9, !noundef !4
%4 = sub i8 %3, 2
%5 = icmp eq i8 %4, 0
%_6 = select i1 %5, i64 0, i64 1
%6 = icmp eq i64 %_6, 0
br i1 %6, label %bb4, label %bb2
bb3: ; No predecessors!
unreachable
```
This has a surprisingly large effect on compile times, with reductions of 5% on debug builds of some crates. The reduction is all due to LLVM taking less time. Maybe LLVM is just much better at handling `br` than `switch`.
The resulting code is still suboptimal.
- The `icmp`, `select`, `icmp` sequence is silly, converting an `i1` to an `i64` and back to an `i1`. But with the current code structure it's hard to avoid, and LLVM will easily clean it up, in opt builds at least.
- `bb3` is usually now truly dead code (though not always, so it can't be removed universally).
r? `@scottmcm`
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/asm.rs')
0 files changed, 0 insertions, 0 deletions
