diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-05-02 19:37:56 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-02 19:37:56 +0200 |
| commit | a2ae171b97741ebf1f7c3e7a1ca118faa91d6662 (patch) | |
| tree | 752e491ecefb5bbfc86e98925ae0e6f671dad531 /compiler/rustc_span/src | |
| parent | 7c96085b64580af5c5f619384f0e3f082138ff13 (diff) | |
| parent | d9c060b88be29569e615496e20bdcf8ecdf780f8 (diff) | |
| download | rust-a2ae171b97741ebf1f7c3e7a1ca118faa91d6662.tar.gz rust-a2ae171b97741ebf1f7c3e7a1ca118faa91d6662.zip | |
Rollup merge of #140485 - Jarcho:from_expansion_opt, r=petrochenkov
Optimize the codegen for `Span::from_expansion`
See https://godbolt.org/z/bq65Y6bc4 for the difference. the new version is less than half the number of instructions.
Also tried fully writing the function by hand:
```rust
sp.ctxt_or_parent_or_marker != 0
&& (
sp.len_with_tag_or_marker == BASE_LEN_INTERNED_MARKER
|| sp.len_with_tag_or_marker & PARENT_TAG == 0
)
```
But that was no better than this PR's current use of `match_span_kind`.
Diffstat (limited to 'compiler/rustc_span/src')
| -rw-r--r-- | compiler/rustc_span/src/span_encoding.rs | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 9d6c7d2a42a..a4a47dc99b0 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -306,8 +306,21 @@ impl Span { /// Returns `true` if this span comes from any kind of macro, desugaring or inlining. #[inline] pub fn from_expansion(self) -> bool { - // If the span is fully inferred then ctxt > MAX_CTXT - self.inline_ctxt().map_or(true, |ctxt| !ctxt.is_root()) + let ctxt = match_span_kind! { + self, + // All branches here, except `InlineParent`, actually return `span.ctxt_or_parent_or_marker`. + // Since `Interned` is selected if the field contains `CTXT_INTERNED_MARKER` returning that value + // as the context allows the compiler to optimize out the branch that selects between either + // `Interned` and `PartiallyInterned`. + // + // Interned contexts can never be the root context and `CTXT_INTERNED_MARKER` has a different value + // than the root context so this works for checking is this is an expansion. + InlineCtxt(span) => SyntaxContext::from_u16(span.ctxt), + InlineParent(_span) => SyntaxContext::root(), + PartiallyInterned(span) => SyntaxContext::from_u16(span.ctxt), + Interned(_span) => SyntaxContext::from_u16(CTXT_INTERNED_MARKER), + }; + !ctxt.is_root() } /// Returns `true` if this is a dummy span with any hygienic context. |
