From 32cfc32a5137bf3e2360a845ea9d8f3682cb0287 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 15 Dec 2015 23:46:38 +0100 Subject: [PATCH 1/4] noalias --- text/0000-noalias.md | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 text/0000-noalias.md diff --git a/text/0000-noalias.md b/text/0000-noalias.md new file mode 100644 index 00000000000..ba42d7f8fdf --- /dev/null +++ b/text/0000-noalias.md @@ -0,0 +1,84 @@ +- Feature Name: noalias +- Start Date: 2015-12-15 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +Add a `noalias` language item and wrapper struct (similar to `non_zero`) to +mark raw pointers as `noalias`. + +# Motivation +[motivation]: #motivation + +Consider the following code: + +```rust +#[no_mangle] +pub extern fn bx(mut x: Box, mut y: Box) -> u8 { + *x = 11; + *y = 22; + *x +} + +#[no_mangle] +pub extern fn rf(x: &mut u8, y: &mut u8) -> u8 { + *x = 11; + *y = 22; + *x +} +``` + +where `Box` is an owning pointer and `Dummy` is an allocator that does not +perform any deallocation. (This setup was chosen so that the following assembly +is as simple as possible.) This produces the following output: + +``` +bx: + movb $11, (%rdi) + movb $22, (%rdx) + movb (%rdi), %al + retq + +rf: + movb $11, (%rdi) + movb $22, (%rsi) + movb $11, %al + retq +``` + +In the `bx` case the value stored in `x` has to be reloaded because the pointer +wrapped by `y` might alias the pointer wrapped by `x`. That is, the second write +might overwrite the value stored in `x`. + +# Detailed design +[design]: #detailed-design + +Add a `noalias` language item and wrapper struct: + +```rust +#[lang = "noalias"] +pub struct NoAlias(*const T); +``` + +Memory access via a pointer `x` +[based on](http://llvm.org/docs/LangRef.html#pointeraliasing) a pointer `y` +wrapped in a `NoAlias` struct does +[not alias](http://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata) +with memory access via pointers not based on `y`. + +# Drawbacks +[drawbacks]: #drawbacks + +None. + +# Alternatives +[alternatives]: #alternatives + +None. + +# Unresolved questions +[unresolved]: #unresolved-questions + +None at the moment. From d4bdada44d5dea98923f36aecaa4ece68b292c92 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 16 Dec 2015 20:22:18 +0100 Subject: [PATCH 2/4] v2 --- text/0000-noalias.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/text/0000-noalias.md b/text/0000-noalias.md index ba42d7f8fdf..9e7f14abe3a 100644 --- a/text/0000-noalias.md +++ b/text/0000-noalias.md @@ -55,6 +55,9 @@ might overwrite the value stored in `x`. # Detailed design [design]: #detailed-design +Two memory accesses are said to alias if at least one of them mutates memory +and the memory ranges they access intersect. + Add a `noalias` language item and wrapper struct: ```rust @@ -62,11 +65,17 @@ Add a `noalias` language item and wrapper struct: pub struct NoAlias(*const T); ``` -Memory access via a pointer `x` -[based on](http://llvm.org/docs/LangRef.html#pointeraliasing) a pointer `y` -wrapped in a `NoAlias` struct does -[not alias](http://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata) -with memory access via pointers not based on `y`. +A pointer is called a noalias pointer if it is stored in a `NoAlias` object. Two +noalias pointers are said to be different if they are stored in different +objects. (Note: Two different noalias pointers can point to the same address.) + +If `x` and `y` are different noalias pointers and `a` and `b` are two pointers +[based on](http://llvm.org/docs/LangRef.html#pointeraliasing) +`x` and `y` respectively, then memory access via `a` and `b` does not +alias. + +If `x` is a noalias pointer, `a` is based on `x`, and `b` is any pointer, then +memory access via `a` and `b` does not alias unless `b` is based on `x`. # Drawbacks [drawbacks]: #drawbacks From 55673e1740ed1c281d2f49b56cda8bdaadbb8db9 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 16 Dec 2015 20:31:27 +0100 Subject: [PATCH 3/4] references are noalias --- text/0000-noalias.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text/0000-noalias.md b/text/0000-noalias.md index 9e7f14abe3a..27301ca1d96 100644 --- a/text/0000-noalias.md +++ b/text/0000-noalias.md @@ -74,6 +74,10 @@ If `x` and `y` are different noalias pointers and `a` and `b` are two pointers `x` and `y` respectively, then memory access via `a` and `b` does not alias. +If `x` is a noalias pointer, `y` is a reference, and `a` and `b` are two +pointers based on `x` and `y` respectively, then memory access via `a` and `b` +does not alias. + If `x` is a noalias pointer, `a` is based on `x`, and `b` is any pointer, then memory access via `a` and `b` does not alias unless `b` is based on `x`. From 0a0f00486aaaba37b918ce4d0bbecbe135712ae4 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 16 Dec 2015 20:33:13 +0100 Subject: [PATCH 4/4] Revert "references are noalias" This reverts commit 55673e1740ed1c281d2f49b56cda8bdaadbb8db9. This is wrong and the real case is already covered in the section below. --- text/0000-noalias.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/text/0000-noalias.md b/text/0000-noalias.md index 27301ca1d96..9e7f14abe3a 100644 --- a/text/0000-noalias.md +++ b/text/0000-noalias.md @@ -74,10 +74,6 @@ If `x` and `y` are different noalias pointers and `a` and `b` are two pointers `x` and `y` respectively, then memory access via `a` and `b` does not alias. -If `x` is a noalias pointer, `y` is a reference, and `a` and `b` are two -pointers based on `x` and `y` respectively, then memory access via `a` and `b` -does not alias. - If `x` is a noalias pointer, `a` is based on `x`, and `b` is any pointer, then memory access via `a` and `b` does not alias unless `b` is based on `x`.