-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Optimize lowering of s[start..][0..len]
#15519
Conversation
s[start...][0..len]
s[start...][0..len]
Those diffs look promising! |
The implementation for slicing with sentinels is done without adding a new ZIR instruction (there are 255 with the new - %21 = slice([]const i32, %19!, %3!)
+ %20!= add(%2, %3)
+ %22 = slice([]const i32, %19!, %3!) It's possible that this should have always been included for various checks done in |
@kristoff-it I couldn't find where exactly the Edit: After reading through the autodoc source a little more carefully I added a new |
Assuming the CI passes I think this is now ready for review and merging. In addition to implementing the The added behavior tests do not represent changed behavior but some things that I broke at one point or another - only one or two of these were caught by tests in |
CI failed with a bunch of safety checks like this:
|
It's odd that half of them are passing - as far as I can tell that's a stdlib test that runs on the other targets as well which is failing. I also can't seem to reproduce it locally. |
Hopefully I found it - I don't think I had covered multi-pointers properly, which leads to a question: do we want to allow: fn foo(ptr: [*]const i32, start: usize, len: usize) []const i32 {
return ptr[start..][0..len];
} I don't see a reason not to but it is a change to what the language permits - previously this wouldn't be possible as the first slice would error due to multi-pointers not having a length. |
Ah, that's a great question. Yes, I think this should be allowed. Arguably, even |
I've updated the PR to allow this, along with some behavior tests for it. There is discussion related to this in #14611, in fact this PR (with allowing multi-pointer slicing as |
s[start...][0..len]
s[start..][0..len]
Looks like the new behavior test coverage didn't pass for our self-hosted WebAssembly backend. You are welcome to disable the entire behavior test for that backend and then a contributor to that backend (perhaps @Luukdegram?) can look at it at their leisure. By the way, you can find out about failures like this without waiting for the CI by running the behavior tests locally, like this:
You'll need wasmtime and qemu installed when using those respective flags. |
Will be creating a fix along with the work I'm doing to enable the full test runner for the Webassembly backend as it depends on code that uses this pattern. |
I'm confident that the CI failures are issues with the CI and not the PR - both failing jobs hit the |
Rebased to check the CI fully passes after #15591. |
Great work! |
Closes #15482.
This PR implements a new ZIR instruction
slice_length
to facilitate optimizing lowering of the slice-by-length patterns[start..][0..len]
.This PR makes one change to the change to the language (discussion here): you can now slice a multi-pointer using the slice-by-length syntax, i.e.
ptr[start..][0..len]
; previously, use of this pattern would cause a compile error due to slicing multi-pointers without a end being an error.Taking the example function in the linked issue:
The core change this makes in the ZIR is:
with the rest of the diff being instruction renumbering due to the reduced number of ZIR instructions.
The core part of the change in AIR (with
-OReleaseFast
) is:Todos before merging:
start_src_node_offset
field of theZir.Inst.SliceLength
is needed or can be removed. Result: it seems like this field, along with the.node_offset_slice_start
LazySrcLoc
variant is the only natural way to track the location, unless someone has a good suggestion or strong dislike of it I'll leave it. As far as I can tell other solutions would require knowing how ZIR instructions are ordered and would likely break with future changes to ZIR.s[start..][0..len:sentinel]
s[start..:sentinel][0..len]
s[start..:sentinal_1][0..len:sentinel_2]