From: Daniel Micay Date: Tue, 6 Aug 2013 21:44:40 +0000 (-0400) Subject: add an intrinsic for inbounds GEP X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=7d115c94205dd4b937d29c77d1704aa3f801869e;p=rust.git add an intrinsic for inbounds GEP --- diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 5153296337d..b1e600b9d73 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -888,6 +888,11 @@ fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) { let offset = get_param(decl, first_real_arg + 1); Ret(bcx, GEP(bcx, ptr, [offset])); } + "offset_inbounds" => { + let ptr = get_param(decl, first_real_arg); + let offset = get_param(decl, first_real_arg + 1); + Ret(bcx, InBoundsGEP(bcx, ptr, [offset])); + } "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 42d5527ee43..ad83286c8c1 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -148,7 +148,8 @@ fn store_type_uses(cx: Context, fn_id: def_id) -> @~[type_uses] { "visit_tydesc" | "forget" | "frame_address" | "morestack_addr" => 0, - "offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | + "offset" | "offset_inbounds" | + "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | "memset32" | "memset64" => use_repr, "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ea8a11fc7b3..8623ee546d6 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3481,6 +3481,20 @@ fn param(ccx: @mut CrateCtxt, n: uint) -> ty::t { mutbl: ast::m_imm })) } + "offset_inbounds" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_int() + ], + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + })) + } "memcpy32" => { (1, ~[ diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index dfd11f9227d..98fb132672c 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -272,6 +272,8 @@ pub trait RawPtr { fn is_not_null(&self) -> bool; unsafe fn to_option(&self) -> Option<&T>; fn offset(&self, count: int) -> Self; + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> Self; } /// Extension methods for immutable pointers @@ -304,6 +306,14 @@ unsafe fn to_option(&self) -> Option<&T> { /// Calculates the offset from a pointer. #[inline] fn offset(&self, count: int) -> *T { offset(*self, count) } + + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. + #[inline] + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> *T { + intrinsics::offset_inbounds(self, count) + } } /// Extension methods for mutable pointers @@ -336,6 +346,18 @@ unsafe fn to_option(&self) -> Option<&T> { /// Calculates the offset from a mutable pointer. #[inline] fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) } + + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. An arithmetic overflow is also + /// undefined behaviour. + /// + /// This method should be preferred over `offset` when the guarantee can be + /// satisfied, to enable better optimization. + #[inline] + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> *mut T { + intrinsics::offset_inbounds(self as *T, count) as *mut T + } } // Equality for pointers diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 1270a80c354..c60edad3dbd 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -317,12 +317,21 @@ fn visit_leave_fn(&self, purity: uint, proto: uint, /// Get the address of the `__morestack` stack growth function. pub fn morestack_addr() -> *(); - /// Adjust a pointer by an offset. + /// Calculates the offset from a pointer. /// /// This is implemented as an intrinsic to avoid converting to and from an /// integer, since the conversion would throw away aliasing information. pub fn offset(dst: *T, offset: int) -> *T; + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. An arithmetic overflow is also + /// undefined behaviour. + /// + /// This intrinsic should be preferred over `offset` when the guarantee can + /// be satisfied, to enable better optimization. + #[cfg(not(stage0))] + pub fn offset_inbounds(dst: *T, offset: int) -> *T; + /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` pub fn memcpy32(dst: *mut T, src: *T, count: u32);