]> git.lizzy.rs Git - rust.git/commitdiff
add an intrinsic for inbounds GEP
authorDaniel Micay <danielmicay@gmail.com>
Tue, 6 Aug 2013 21:44:40 +0000 (17:44 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Wed, 7 Aug 2013 03:41:20 +0000 (23:41 -0400)
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/type_use.rs
src/librustc/middle/typeck/check/mod.rs
src/libstd/ptr.rs
src/libstd/unstable/intrinsics.rs

index 5153296337daed25055c7751d7d680c61abc37f5..b1e600b9d7376f5466d53ba06a500a948fe8e90d 100644 (file)
@@ -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),
index 42d5527ee43bc39bced200bcb0eed0737d7e792f..ad83286c8c1d75a60353ab2a36c2f248f0665f26 100644 (file)
@@ -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" |
index ea8a11fc7b3821b425f4ee3fac59c6927a712bb6..8623ee546d6603a0c6cb2ff52b7e31afb299a16e 100644 (file)
@@ -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,
                ~[
index dfd11f9227d413e5b37725b91a34e54d024f3eea..98fb132672c6e34d09de3c8868ca8123c15dc5bd 100644 (file)
@@ -272,6 +272,8 @@ pub trait RawPtr<T> {
     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
index 1270a80c354990aeee037520b1fe4f1221faf192..c60edad3dbd5683e6ec69cae281376a950089a6c 100644 (file)
@@ -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<T>(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<T>(dst: *T, offset: int) -> *T;
+
     /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
     pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);