Есть ли способ заставить Rust обрабатывать указатели как сглаживание, поэтому он может обозначать их как "noalias" для оптимизатора LLVM?
Следующий пример сглаживания указателя:
pub unsafe fn f(a: *mut i32, b: *mut i32, x: *const i32) {
*a = *x;
*b = *x;
}
компилируется в следующую сборку (с помощью -C opt-level=s
):
example::f:
push rbp
mov rbp, rsp
mov eax, dword ptr [rdx]
mov dword ptr [rdi], eax
mov eax, dword ptr [rdx]
mov dword ptr [rsi], eax
pop rbp
ret
Обратите внимание, что x
разыменовывается дважды. LLVM не рассматривает его как noalias
. Моя первая мысль заключалась в том, чтобы избежать использования указателей в назначениях и вместо этого использовать безопасные ссылки (поскольку те
pub fn g(a: *mut i32, b: *mut i32, x: *const i32) {
let safe_a = unsafe { &mut *a };
let safe_b = unsafe { &mut *b };
let safe_x = unsafe { &*x };
*safe_a = *safe_x;
*safe_b = *safe_x;
}
Но, увы, это дает точный результат. safe_x
по-прежнему разыменовывается дважды.