From 889e1b9731615a6b03b0e46662edb70c6ca7e7ad Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 9 Sep 2013 02:32:30 -0400 Subject: [PATCH] add `noalias` attribute to ~ return values --- src/librustc/lib/llvm.rs | 6 ++++++ src/librustc/middle/trans/base.rs | 24 +++++++++++++++--------- src/rustllvm/RustWrapper.cpp | 15 +++++++++++++++ src/rustllvm/rustllvm.def.in | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 9e81ee5e64c..34c0dbb1788 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -873,6 +873,12 @@ pub mod llvm { pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char); #[fast_ffi] pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong; + + #[fast_ffi] + pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint); + #[fast_ffi] + pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint); + #[fast_ffi] pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 9e281172b26..d964e89ab8e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1716,21 +1716,15 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext, let llarg = unsafe {llvm::LLVMGetParam(cx.llfn, arg_n as c_uint) }; match ty::get(arg_ty).sty { - // `~` pointers never alias other parameters, because - // ownership was transferred + // `~` pointer parameters never alias because ownership is transferred ty::ty_uniq(*) | ty::ty_evec(_, ty::vstore_uniq) | ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => { unsafe { - llvm::LLVMAddAttribute( - llarg, lib::llvm::NoAliasAttribute as c_uint); + llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint); } } - // FIXME: #6785: `&mut` can only alias `&const` and - // `@mut`, we should check for those in the other - // parameters and then mark it as `noalias` if there - // aren't any - _ => {} + _ => () } llarg @@ -1952,6 +1946,18 @@ pub fn trans_fn(ccx: @mut CrateContext, param_substs.repr(ccx.tcx)); let _icx = push_ctxt("trans_fn"); let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id)); + + match ty::get(output_type).sty { + // `~` pointer return values never alias because ownership is transferred + ty::ty_uniq(*) | + ty::ty_evec(_, ty::vstore_uniq) => { + unsafe { + llvm::LLVMAddReturnAttribute(llfndecl, lib::llvm::NoAliasAttribute as c_uint); + } + } + _ => () + } + trans_closure(ccx, path.clone(), decl, diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 376adf24e25..226a7c34304 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -350,6 +350,21 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) { unwrap(fn)->addFnAttr(Name); } + +extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) { + Function *A = unwrap(Fn); + AttrBuilder B(PA); + A->addAttributes(AttributeSet::ReturnIndex, + AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B)); +} + +extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) { + Function *A = unwrap(Fn); + AttrBuilder B(PA); + A->removeAttributes(AttributeSet::ReturnIndex, + AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B)); +} + extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef source, const char* Name, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 79cfe8b2851..d905370f587 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -624,3 +624,5 @@ LLVMRustSetLLVMOptions LLVMRustPrintPasses LLVMRustSetNormalizedTarget LLVMRustAddAlwaysInlinePass +LLVMAddReturnAttribute +LLVMRemoveReturnAttribute