Skip to content

Commit 889e1b9

Browse files
committed
add noalias attribute to ~ return values
1 parent dd5c737 commit 889e1b9

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

src/librustc/lib/llvm.rs

+6
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,12 @@ pub mod llvm {
873873
pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
874874
#[fast_ffi]
875875
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
876+
877+
#[fast_ffi]
878+
pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
879+
#[fast_ffi]
880+
pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint);
881+
876882
#[fast_ffi]
877883
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
878884
PA: c_ulonglong,

src/librustc/middle/trans/base.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1716,21 +1716,15 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
17161716
let llarg = unsafe {llvm::LLVMGetParam(cx.llfn, arg_n as c_uint) };
17171717

17181718
match ty::get(arg_ty).sty {
1719-
// `~` pointers never alias other parameters, because
1720-
// ownership was transferred
1719+
// `~` pointer parameters never alias because ownership is transferred
17211720
ty::ty_uniq(*) |
17221721
ty::ty_evec(_, ty::vstore_uniq) |
17231722
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
17241723
unsafe {
1725-
llvm::LLVMAddAttribute(
1726-
llarg, lib::llvm::NoAliasAttribute as c_uint);
1724+
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
17271725
}
17281726
}
1729-
// FIXME: #6785: `&mut` can only alias `&const` and
1730-
// `@mut`, we should check for those in the other
1731-
// parameters and then mark it as `noalias` if there
1732-
// aren't any
1733-
_ => {}
1727+
_ => ()
17341728
}
17351729

17361730
llarg
@@ -1952,6 +1946,18 @@ pub fn trans_fn(ccx: @mut CrateContext,
19521946
param_substs.repr(ccx.tcx));
19531947
let _icx = push_ctxt("trans_fn");
19541948
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
1949+
1950+
match ty::get(output_type).sty {
1951+
// `~` pointer return values never alias because ownership is transferred
1952+
ty::ty_uniq(*) |
1953+
ty::ty_evec(_, ty::vstore_uniq) => {
1954+
unsafe {
1955+
llvm::LLVMAddReturnAttribute(llfndecl, lib::llvm::NoAliasAttribute as c_uint);
1956+
}
1957+
}
1958+
_ => ()
1959+
}
1960+
19551961
trans_closure(ccx,
19561962
path.clone(),
19571963
decl,

src/rustllvm/RustWrapper.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,21 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
350350
unwrap<Function>(fn)->addFnAttr(Name);
351351
}
352352

353+
354+
extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
355+
Function *A = unwrap<Function>(Fn);
356+
AttrBuilder B(PA);
357+
A->addAttributes(AttributeSet::ReturnIndex,
358+
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
359+
}
360+
361+
extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
362+
Function *A = unwrap<Function>(Fn);
363+
AttrBuilder B(PA);
364+
A->removeAttributes(AttributeSet::ReturnIndex,
365+
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
366+
}
367+
353368
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
354369
LLVMValueRef source,
355370
const char* Name,

src/rustllvm/rustllvm.def.in

+2
Original file line numberDiff line numberDiff line change
@@ -624,3 +624,5 @@ LLVMRustSetLLVMOptions
624624
LLVMRustPrintPasses
625625
LLVMRustSetNormalizedTarget
626626
LLVMRustAddAlwaysInlinePass
627+
LLVMAddReturnAttribute
628+
LLVMRemoveReturnAttribute

0 commit comments

Comments
 (0)