auto merge of #13935 : thestinger/rust/noalias, r=pcwalton
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
This commit is contained in:
commit
2be738ae36
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue