Emit !nonnull metadata for loads of region and unique pointers
These pointers are never null, let's tell LLVM about it.
This commit is contained in:
parent
7858cb432d
commit
1a56a1a515
4 changed files with 37 additions and 1 deletions
|
@ -377,7 +377,13 @@ pub enum MetadataType {
|
||||||
MD_prof = 2,
|
MD_prof = 2,
|
||||||
MD_fpmath = 3,
|
MD_fpmath = 3,
|
||||||
MD_range = 4,
|
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
|
// Inline Asm Dialect
|
||||||
|
|
|
@ -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
|
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
|
||||||
// and we have to convert it
|
// and we have to convert it
|
||||||
Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to()))
|
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) {
|
} else if ty::type_is_char(t) {
|
||||||
// a char is a Unicode codepoint, and so takes values from 0
|
// a char is a Unicode codepoint, and so takes values from 0
|
||||||
// to 0x10FFFF inclusive only.
|
// to 0x10FFFF inclusive only.
|
||||||
|
|
|
@ -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) {
|
pub fn Store(cx: Block, val: ValueRef, ptr: ValueRef) {
|
||||||
if cx.unreachable.get() { return; }
|
if cx.unreachable.get() { return; }
|
||||||
B(cx).store(val, ptr)
|
B(cx).store(val, ptr)
|
||||||
|
|
|
@ -22,6 +22,7 @@ use util::nodemap::FnvHashMap;
|
||||||
use libc::{c_uint, c_char};
|
use libc::{c_uint, c_char};
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::ptr;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
|
|
||||||
pub struct Builder<'a, 'tcx: 'a> {
|
pub struct Builder<'a, 'tcx: 'a> {
|
||||||
|
@ -498,6 +499,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
value
|
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) {
|
pub fn store(&self, val: ValueRef, ptr: ValueRef) {
|
||||||
debug!("Store {} -> {}",
|
debug!("Store {} -> {}",
|
||||||
self.ccx.tn().val_to_string(val),
|
self.ccx.tn().val_to_string(val),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue