Update InterpCx::project_field to take FieldIdx#142103
Update InterpCx::project_field to take FieldIdx#142103bors merged 2 commits intorust-lang:masterfrom
InterpCx::project_field to take FieldIdx#142103Conversation
|
Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred in compiler/rustc_codegen_ssa Some changes occurred to the CTFE machinery Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt The Miri subtree was changed cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
As suggested by Ralf in 142005.
74c269e to
8bce225
Compare
oli-obk
left a comment
There was a problem hiding this comment.
This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later
| return None; | ||
| } | ||
| found = Some((field_idx, field)); | ||
| found = Some((FieldIdx::from_usize(field_idx), field)); |
There was a problem hiding this comment.
it may be worth adding an iter and an iter_enumerated method to FieldsShape
There was a problem hiding this comment.
Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.
(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)
|
@bors r+ rollup |
| impl FieldIdx { | ||
| /// The second field. | ||
| /// | ||
| /// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs. |
There was a problem hiding this comment.
Why is this not defined near FieldIdx::ZERO?
There was a problem hiding this comment.
Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.
There was a problem hiding this comment.
There was a problem hiding this comment.
You can add a const ONE = 1; in the macro to get it generated.
There was a problem hiding this comment.
That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.
| let fields_iter = (0..field_count) | ||
| .map(|i| { | ||
| let field_op = ecx.project_field(&down, i).discard_err()?; | ||
| let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?; |
There was a problem hiding this comment.
This could also use a typed field iterator
|
|
||
| for i in 0..field_count { | ||
| let field = ecx.project_field(&place, i).unwrap(); | ||
| let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); |
There was a problem hiding this comment.
And more here
(probably not worth pointing them all out)
| // Computing the layout does normalization, so we get a normalized type out of this | ||
| // even if the field type is non-normalized (possible e.g. via associated types). | ||
| let field_layout = base.layout().field(self, field); | ||
| let field_layout = base.layout().field(self, field.as_usize()); |
There was a problem hiding this comment.
Why does field not take FieldIdx...?
There was a problem hiding this comment.
It's https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.TyAndLayout.html#method.field, I think. And that's like I mentioned in #142005 (comment) something that takes usize today, because it works on arrays https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/layout.rs.html#795-998.
Co-authored-by: Ralf Jung <post@ralfj.de>
|
@bors r=oli-obk |
|
Yeah those should be separate methods for fields and array elements.
Is this entire project tracked somewhere? (Also re: field iterators)
|
|
I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs. |
Rollup of 11 pull requests Successful merges: - #140418 (Reexport types from `c_size_t` in `std`) - #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract) - #141603 (Reduce `ast::ptr::P` to a typedef of `Box`) - #142043 (Verbose suggestion to make param `const`) - #142086 (duduplicate more AST visitor methods) - #142103 (Update `InterpCx::project_field` to take `FieldIdx`) - #142105 (remove extraneous text) - #142112 (fix typo) - #142113 (Reduce confusion of some drop order tests) - #142114 (Compute number of digits instead of relying on constant value for u128 display code) - #142118 (rustc_lexer: typo fix + small cleanups) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk Update `InterpCx::project_field` to take `FieldIdx` As suggested by Ralf in #142005 (comment)
Rollup of 11 pull requests Successful merges: - rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`) - rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract) - rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`) - rust-lang/rust#142043 (Verbose suggestion to make param `const`) - rust-lang/rust#142086 (duduplicate more AST visitor methods) - rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`) - rust-lang/rust#142105 (remove extraneous text) - rust-lang/rust#142112 (fix typo) - rust-lang/rust#142113 (Reduce confusion of some drop order tests) - rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code) - rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups) r? `@ghost` `@rustbot` modify labels: rollup
Oh. Did I mean to work on it and then forgot? 😓 |
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383
…-obk Update `InterpCx::project_field` to take `FieldIdx` As suggested by Ralf in rust-lang#142005 (comment)
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - #142005 - #142103 - #142324 - #142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - rust-lang/rust#142005 - rust-lang/rust#142103 - rust-lang/rust#142324 - rust-lang/rust#142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - rust-lang/rust#142005 - rust-lang/rust#142103 - rust-lang/rust#142324 - rust-lang/rust#142383 --- try-job: aarch64-gnu
Allow `enum` and `union` literals to also create SSA values Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value. For example, <https://rust.godbolt.org/z/6KG6PqoYz> ```rust pub fn demo(r: &i32) -> Option<&i32> { Some(r) } ``` currently emits the IR ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: %_0 = alloca [8 x i8], align 8 store ptr %r, ptr %_0, align 8 %0 = load ptr, ptr %_0, align 8 ret ptr %0 } ``` but with this PR it becomes just ```llvm define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr { start: ret ptr %r } ``` (Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.) Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc. Other PRs that led up to this one: - rust-lang/rust#142005 - rust-lang/rust#142103 - rust-lang/rust#142324 - rust-lang/rust#142383 --- try-job: aarch64-gnu
Rollup of 11 pull requests Successful merges: - rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`) - rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract) - rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`) - rust-lang/rust#142043 (Verbose suggestion to make param `const`) - rust-lang/rust#142086 (duduplicate more AST visitor methods) - rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`) - rust-lang/rust#142105 (remove extraneous text) - rust-lang/rust#142112 (fix typo) - rust-lang/rust#142113 (Reduce confusion of some drop order tests) - rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code) - rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 11 pull requests Successful merges: - rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`) - rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract) - rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`) - rust-lang/rust#142043 (Verbose suggestion to make param `const`) - rust-lang/rust#142086 (duduplicate more AST visitor methods) - rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`) - rust-lang/rust#142105 (remove extraneous text) - rust-lang/rust#142112 (fix typo) - rust-lang/rust#142113 (Reduce confusion of some drop order tests) - rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code) - rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups) r? `@ghost` `@rustbot` modify labels: rollup
As suggested by Ralf in #142005 (comment)