about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-04 20:03:55 +0000
committerbors <bors@rust-lang.org>2015-02-04 20:03:55 +0000
commitba2f13ef0667ce90f55ab0f1506bf5ee7b852d96 (patch)
treeac7d63102af2153d66beff88a388e08a5159d044
parent3ae76d5c1cca83eff3a4716550da357ca2abcd21 (diff)
parent1a56a1a515ef2cda3425ff09bac9504a77616fec (diff)
downloadrust-ba2f13ef0667ce90f55ab0f1506bf5ee7b852d96.tar.gz
rust-ba2f13ef0667ce90f55ab0f1506bf5ee7b852d96.zip
Auto merge of #21885 - dotdash:nonnull_load, r=alexcrichton
These pointers are never null, let's tell LLVM about it.
-rw-r--r--src/librustc_llvm/lib.rs8
-rw-r--r--src/librustc_trans/trans/base.rs2
-rw-r--r--src/librustc_trans/trans/build.rs17
-rw-r--r--src/librustc_trans/trans/builder.rs11
4 files changed, 37 insertions, 1 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index a1532c044e3..26af9c9622f 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -377,7 +377,13 @@ pub enum MetadataType {
     MD_prof = 2,
     MD_fpmath = 3,
     MD_range = 4,
-    MD_tbaa_struct = 5
+    MD_tbaa_struct = 5,
+    MD_invariant_load = 6,
+    MD_alias_scope = 7,
+    MD_noalias = 8,
+    MD_nontemporal = 9,
+    MD_mem_parallel_loop_access = 10,
+    MD_nonnull = 11,
 }
 
 // Inline Asm Dialect
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 6901eb25b31..c2af6ec8c8a 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -1033,6 +1033,8 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
         // for this leads to bad optimizations, so its arg type is an appropriately sized integer
         // and we have to convert it
         Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to()))
+    } else if ty::type_is_region_ptr(t) || ty::type_is_unique(t) {
+        LoadNonNull(cx, ptr)
     } else if ty::type_is_char(t) {
         // a char is a Unicode codepoint, and so takes values from 0
         // to 0x10FFFF inclusive only.
diff --git a/src/librustc_trans/trans/build.rs b/src/librustc_trans/trans/build.rs
index 7acac5a12eb..c288a8196e6 100644
--- a/src/librustc_trans/trans/build.rs
+++ b/src/librustc_trans/trans/build.rs
@@ -629,6 +629,23 @@ pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64,
     }
 }
 
+pub fn LoadNonNull(cx: Block, ptr: ValueRef) -> ValueRef {
+    if cx.unreachable.get() {
+        let ccx = cx.fcx.ccx;
+        let ty = val_ty(ptr);
+        let eltty = if ty.kind() == llvm::Array {
+            ty.element_type()
+        } else {
+            ccx.int_type()
+        };
+        unsafe {
+            llvm::LLVMGetUndef(eltty.to_ref())
+        }
+    } else {
+        B(cx).load_nonnull(ptr)
+    }
+}
+
 pub fn Store(cx: Block, val: ValueRef, ptr: ValueRef) {
     if cx.unreachable.get() { return; }
     B(cx).store(val, ptr)
diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs
index 32e16c7bf8d..e268c2f0d5c 100644
--- a/src/librustc_trans/trans/builder.rs
+++ b/src/librustc_trans/trans/builder.rs
@@ -22,6 +22,7 @@ use util::nodemap::FnvHashMap;
 use libc::{c_uint, c_char};
 
 use std::ffi::CString;
+use std::ptr;
 use syntax::codemap::Span;
 
 pub struct Builder<'a, 'tcx: 'a> {
@@ -498,6 +499,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         value
     }
 
+    pub fn load_nonnull(&self, ptr: ValueRef) -> ValueRef {
+        let value = self.load(ptr);
+        unsafe {
+            llvm::LLVMSetMetadata(value, llvm::MD_nonnull as c_uint,
+                                  llvm::LLVMMDNodeInContext(self.ccx.llcx(), ptr::null(), 0));
+        }
+
+        value
+    }
+
     pub fn store(&self, val: ValueRef, ptr: ValueRef) {
         debug!("Store {} -> {}",
                self.ccx.tn().val_to_string(val),