]> git.lizzy.rs Git - rust.git/commitdiff
Emit !nonnull metadata for loads of region and unique pointers
authorBjörn Steinbrink <bsteinbr@gmail.com>
Mon, 2 Feb 2015 18:03:23 +0000 (19:03 +0100)
committerBjörn Steinbrink <bsteinbr@gmail.com>
Tue, 3 Feb 2015 07:55:04 +0000 (08:55 +0100)
These pointers are never null, let's tell LLVM about it.

src/librustc_llvm/lib.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/build.rs
src/librustc_trans/trans/builder.rs

index a1532c044e3dcd5fdbd7e772998d89a4f5f741f7..26af9c9622ffe785b79c1f9c456b5bcfd388772e 100644 (file)
@@ -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
index 9e561fc883bb043366e5c7de7198d9863b5e3323..64cffaf08b4c09da366b543f0103e57fa0a39434 100644 (file)
@@ -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.
index 7acac5a12ebd216c8e1132b477881b5512a8a17e..c288a8196e63c0b8e9fcbe53fc5e3fa41cf49a8a 100644 (file)
@@ -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)
index 32e16c7bf8d98c07633eee6a0a5142175d4f4671..e268c2f0d5cc2b1dc766d7aab821f62e41894fe3 100644 (file)
@@ -22,6 +22,7 @@
 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 @@ pub fn load_range_assert(&self, ptr: ValueRef, lo: u64,
         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),