Skip to content

Tell LLVM when a match is exhaustive #28651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 27, 2015
Merged

Conversation

dotdash
Copy link
Contributor

@dotdash dotdash commented Sep 25, 2015

By putting an "unreachable" instruction into the default arm of a switch
instruction we can let LLVM know that the match is exhaustive, allowing
for better optimizations.

For example, this match:

pub enum Enum {
    One,
    Two,
    Three,
}

impl Enum {
    pub fn get_disc(self) -> u8 {
        match self {
            Enum::One => 0,
            Enum::Two => 1,
            Enum::Three => 2,
        }
    }
}

Currently compiles to this on x86_64:

  .cfi_startproc
  movzbl  %dil, %ecx
  cmpl  $1, %ecx
  setne %al
  testb %cl, %cl
  je  .LBB0_2
  incb  %al
  movb  %al, %dil
.LBB0_2:
  movb  %dil, %al
  retq
.Lfunc_end0:

But with this change we get:

  .cfi_startproc
  movb  %dil, %al
  retq
.Lfunc_end0:

By putting an "unreachable" instruction into the default arm of a switch
instruction we can let LLVM know that the match is exhaustive, allowing
for better optimizations.

For example, this match:
```rust
pub enum Enum {
    One,
    Two,
    Three,
}

impl Enum {
    pub fn get_disc(self) -> u8 {
        match self {
            Enum::One => 0,
            Enum::Two => 1,
            Enum::Three => 2,
        }
    }
}
```

Currently compiles to this on x86_64:
```asm
  .cfi_startproc
  movzbl  %dil, %ecx
  cmpl  $1, %ecx
  setne %al
  testb %cl, %cl
  je  .LBB0_2
  incb  %al
  movb  %al, %dil
.LBB0_2:
  movb  %dil, %al
  retq
.Lfunc_end0:
```

But with this change we get:
```asm
  .cfi_startproc
  movb  %dil, %al
  retq
.Lfunc_end0:
```
@rust-highfive
Copy link
Contributor

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

@eddyb
Copy link
Member

eddyb commented Sep 25, 2015

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 25, 2015

📌 Commit 91f7c60 has been approved by eddyb

@bors
Copy link
Collaborator

bors commented Sep 27, 2015

⌛ Testing commit 91f7c60 with merge dde7283...

bors added a commit that referenced this pull request Sep 27, 2015
By putting an "unreachable" instruction into the default arm of a switch
instruction we can let LLVM know that the match is exhaustive, allowing
for better optimizations.

For example, this match:
```rust
pub enum Enum {
    One,
    Two,
    Three,
}

impl Enum {
    pub fn get_disc(self) -> u8 {
        match self {
            Enum::One => 0,
            Enum::Two => 1,
            Enum::Three => 2,
        }
    }
}
```

Currently compiles to this on x86_64:
```asm
  .cfi_startproc
  movzbl  %dil, %ecx
  cmpl  $1, %ecx
  setne %al
  testb %cl, %cl
  je  .LBB0_2
  incb  %al
  movb  %al, %dil
.LBB0_2:
  movb  %dil, %al
  retq
.Lfunc_end0:
```

But with this change we get:
```asm
  .cfi_startproc
  movb  %dil, %al
  retq
.Lfunc_end0:
```
@bors bors merged commit 91f7c60 into rust-lang:master Sep 27, 2015
@brson brson added the relnotes Marks issues that should be documented in the release notes of the next release. label Oct 2, 2015
@brson
Copy link
Contributor

brson commented Oct 2, 2015

Looks like a big win.

@dotdash
Copy link
Contributor Author

dotdash commented Oct 3, 2015

It might be in some cases, but unfortunately I don't know of any practical
example where this makes a major difference.
Am 02.10.2015 20:41 schrieb "Brian Anderson" [email protected]:

Looks like a big win.


Reply to this email directly or view it on GitHub
#28651 (comment).

@dotdash
Copy link
Contributor Author

dotdash commented Oct 3, 2015

@eddyb you reminded me of this. Do you have a good use case for it?
Am 03.10.2015 03:46 schrieb "Björn Steinbrink" [email protected]:

It might be in some cases, but unfortunately I don't know of any practical
example where this makes a major difference.
Am 02.10.2015 20:41 schrieb "Brian Anderson" [email protected]:

Looks like a big win.


Reply to this email directly or view it on GitHub
#28651 (comment).

@eddyb
Copy link
Member

eddyb commented Oct 3, 2015

Not really, other than "get a number from each enum variant" which showed up in #rust-offtopic and prompted me to check the IR for inefficiencies.

@dotdash dotdash deleted the exhaustive_match branch January 15, 2016 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants