add noalias attribute to ~ return values

This commit is contained in:
Daniel Micay 2013-09-09 02:32:30 -04:00
parent dd5c7379e9
commit 889e1b9731
4 changed files with 38 additions and 9 deletions

View File

@ -873,6 +873,12 @@ pub fn LLVMGetOrInsertFunction(M: ModuleRef,
pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char); pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
#[fast_ffi] #[fast_ffi]
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong; 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] #[fast_ffi]
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
PA: c_ulonglong, PA: c_ulonglong,

View File

@ -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) }; let llarg = unsafe {llvm::LLVMGetParam(cx.llfn, arg_n as c_uint) };
match ty::get(arg_ty).sty { match ty::get(arg_ty).sty {
// `~` pointers never alias other parameters, because // `~` pointer parameters never alias because ownership is transferred
// ownership was transferred
ty::ty_uniq(*) | ty::ty_uniq(*) |
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) |
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => { ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
unsafe { unsafe {
llvm::LLVMAddAttribute( llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
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 llarg
@ -1952,6 +1946,18 @@ pub fn trans_fn(ccx: @mut CrateContext,
param_substs.repr(ccx.tcx)); param_substs.repr(ccx.tcx));
let _icx = push_ctxt("trans_fn"); let _icx = push_ctxt("trans_fn");
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id)); 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, trans_closure(ccx,
path.clone(), path.clone(),
decl, decl,

View File

@ -350,6 +350,21 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
unwrap<Function>(fn)->addFnAttr(Name); unwrap<Function>(fn)->addFnAttr(Name);
} }
extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
Function *A = unwrap<Function>(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<Function>(Fn);
AttrBuilder B(PA);
A->removeAttributes(AttributeSet::ReturnIndex,
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
}
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
LLVMValueRef source, LLVMValueRef source,
const char* Name, const char* Name,

View File

@ -624,3 +624,5 @@ LLVMRustSetLLVMOptions
LLVMRustPrintPasses LLVMRustPrintPasses
LLVMRustSetNormalizedTarget LLVMRustSetNormalizedTarget
LLVMRustAddAlwaysInlinePass LLVMRustAddAlwaysInlinePass
LLVMAddReturnAttribute
LLVMRemoveReturnAttribute