Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upnoalias is not enough #53105
Comments
This comment has been minimized.
This comment has been minimized.
Ah, good point. Read-write data races "just" make the read yield
Correct. AFAIK,
Oh yes, it is very much stronger in various ways. |
This comment has been minimized.
This comment has been minimized.
|
Isn't this the sort of thing the |
This comment has been minimized.
This comment has been minimized.
|
@varkor what would be the scopes for the |
This comment has been minimized.
This comment has been minimized.
|
In this example, as you point out, the aliasing is important with regards to memory accesses outside the function. So if in theory you could mark all the others... I doubt that's sufficient for LLVM though. |
This comment has been minimized.
This comment has been minimized.
leonardo-m
commented
Aug 9, 2018
|
Is it a good idea to write a LLVM enhancement request? |
This comment has been minimized.
This comment has been minimized.
|
As @varkor says, we could mark all others, and we would have to mark all others for every &mut that the programs creates, and even then, this is not something that alias analysis would take into account because no sane language front-end will do this. Extending LLVM to support this won't be easy either. Currently LLVM hoists memory ops from functions when profitable, but: // T: Copy
fn foo(x: &mut T) {
// in this scope there is only one
// pointer to the value behind x
let y = *x;
...
}
{
let mut z = T;
let ptr = &mut z as *mut T;
// hoist the load from foo out here
foo(&mut z);
*ptr = T;
}so when hoisting the load (or store) from So all the optimizations that currently move memory across scope would need to update and be extremely careful with any attribute/metadata that we might want to use. Maybe a minimal extension to alias analysis that allow us to specify the "opposite" / "negative" aliasing groups would be enough, but one would need to teach many pieces of the pipeline about this for the new information to result in better code gen. |
gnzlbg commentedAug 6, 2018
•
edited
Somebody on the internet (https://blog.dend.ro/rust-and-the-case-of-the-redundant-comparison/) complained that something like this:
generates a conditional store:
on
x86_64instead of just an unconditional storemovl $0, (%rdi); retq.Taking a look at the optimized LLVM-IR:
shows the issue.
The LLVM-IR generated by rustc is loosing critical information. It marks
i32*asnoalias, which means, that no other pointers invec_clear's scope will alias it. However, outsidevec_clearscope, other pointers are allowed to alias that memory. That is, if*xis zero, other threads could be concurrently reading the memory and if LLVM would generate an unconditional store here, that would introduce a data-race, which means that this optimization is not safe on the LLVM-IR generated by rustc. OTOH, &mut i32` means that the pointer has unique access to the memory, that is, no other pointer can access the memory behind it as long as that pointer is alive. Therefore, transforming the code to an unconditional store does not introduce a data-race.Therefore, I think that
noaliasis not enough to perform this optimization and that we would need something stronger for LLVM to be able to perform it.This also shows that
&mut Tis stronger than C'srestrictkeyword.