From f62c753b8f7879607204bcf77491cc81baf9c2dc Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 4 May 2014 12:11:20 -0400 Subject: [PATCH] add back `noalias` to `&mut T` pointer parameters This was removed because these could alias with `&const T` or `@mut T` and those are now gone from the language. There are still aliasing issues within local scopes, but this is correct for function parameters. This also removes the no-op `noalias` marker on proc (not a pointer) and leaves out the mention of #6750 because real type-based alias analysis is not within the scope of best effort usage of the `noalias` attribute. Test case: pub fn foo(x: &mut &mut u32) { **x = 5; **x = 5; } Before: define void @_ZN3foo20h0ce94c9671b0150bdaa4v0.0E(i32** nocapture readonly) unnamed_addr #0 { entry-block: %1 = load i32** %0, align 8 store i32 5, i32* %1, align 4 %2 = load i32** %0, align 8 store i32 5, i32* %2, align 4 ret void } After: define void @_ZN3foo20h0ce94c9671b0150bdaa4v0.0E(i32** noalias nocapture readonly) unnamed_addr #0 { entry-block: %1 = load i32** %0, align 8 store i32 5, i32* %1, align 4 ret void } Closes #12436 --- src/librustc/middle/trans/base.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 55f7b8cbf2447..53a2dc8060572 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -186,8 +186,6 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, } } // `~` pointer return values never alias because ownership is transferred - // FIXME #6750 ~Trait cannot be directly marked as - // noalias because the actual object pointer is nested. ty::ty_uniq(..) // | ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => { unsafe { @@ -258,23 +256,25 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) }; match ty::get(arg_ty).sty { // `~` pointer parameters never alias because ownership is transferred - // FIXME #6750 ~Trait cannot be directly marked as - // noalias because the actual object pointer is nested. - ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) | - ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => { + ty::ty_uniq(..) => { unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); } - }, - // When a reference in an argument has no named lifetime, it's - // impossible for that reference to escape this function(ie, be - // returned). + } + // `&mut` pointer parameters never alias other parameters, or mutable global data + ty::ty_rptr(_, mt) if mt.mutbl == ast::MutMutable => { + unsafe { + llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); + } + } + // When a reference in an argument has no named lifetime, it's impossible for that + // reference to escape this function (returned or stored beyond the call by a closure). ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => { debug!("marking argument of {} as nocapture because of anonymous lifetime", name); unsafe { llvm::LLVMAddAttribute(llarg, lib::llvm::NoCaptureAttribute as c_uint); } - }, + } _ => { // For non-immediate arguments the callee gets its own copy of // the value on the stack, so there are no aliases