about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-09 13:01:02 -0700
committerbors <bors@rust-lang.org>2013-09-09 13:01:02 -0700
commit54ae2800ffb30513f89ce13d27ac3c8d095d98ac (patch)
tree1b7bc33acd05a16a9d1336379e206007c3965069
parent60a0dbc095d83964ba668c89e25261ead3df55f4 (diff)
parent889e1b9731615a6b03b0e46662edb70c6ca7e7ad (diff)
downloadrust-54ae2800ffb30513f89ce13d27ac3c8d095d98ac.tar.gz
rust-54ae2800ffb30513f89ce13d27ac3c8d095d98ac.zip
auto merge of #9071 : thestinger/rust/noalias, r=alexcrichton
This also removes a FIXME I added referring to a now closed issue.
-rw-r--r--src/librustc/lib/llvm.rs6
-rw-r--r--src/librustc/middle/trans/base.rs24
-rw-r--r--src/rustllvm/RustWrapper.cpp15
-rw-r--r--src/rustllvm/rustllvm.def.in2
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<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,
                                             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