about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2016-12-17 18:25:32 -0700
committerMark Simulacrum <mark.simulacrum@gmail.com>2016-12-20 20:03:30 -0700
commit99816a67435dbe2d9343f82ea16753e1c63edbe2 (patch)
tree759ec7f7f370a7970e1bd2e2db40ebf65dec033c /src
parent611e90b11823e8328a9478c6a1c521696d4c5b75 (diff)
downloadrust-99816a67435dbe2d9343f82ea16753e1c63edbe2.tar.gz
rust-99816a67435dbe2d9343f82ea16753e1c63edbe2.zip
Further simplify intrinsic matching
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/intrinsic.rs118
1 files changed, 33 insertions, 85 deletions
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 8501364ba36..17a04c14cba 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -211,44 +211,20 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
         }
 
         "copy_nonoverlapping" => {
-            copy_intrinsic(bcx,
-                           false,
-                           false,
-                           substs.type_at(0),
-                           llargs[1],
-                           llargs[0],
-                           llargs[2])
+            copy_intrinsic(bcx, false, false, substs.type_at(0), llargs[1], llargs[0], llargs[2])
         }
         "copy" => {
-            copy_intrinsic(bcx,
-                           true,
-                           false,
-                           substs.type_at(0),
-                           llargs[1],
-                           llargs[0],
-                           llargs[2])
+            copy_intrinsic(bcx, true, false, substs.type_at(0), llargs[1], llargs[0], llargs[2])
         }
         "write_bytes" => {
             memset_intrinsic(bcx, false, substs.type_at(0), llargs[0], llargs[1], llargs[2])
         }
 
         "volatile_copy_nonoverlapping_memory" => {
-            copy_intrinsic(bcx,
-                           false,
-                           true,
-                           substs.type_at(0),
-                           llargs[0],
-                           llargs[1],
-                           llargs[2])
+            copy_intrinsic(bcx, false, true, substs.type_at(0), llargs[0], llargs[1], llargs[2])
         }
         "volatile_copy_memory" => {
-            copy_intrinsic(bcx,
-                           true,
-                           true,
-                           substs.type_at(0),
-                           llargs[0],
-                           llargs[1],
-                           llargs[2])
+            copy_intrinsic(bcx, true, true, substs.type_at(0), llargs[0], llargs[1], llargs[2])
         }
         "volatile_set_memory" => {
             memset_intrinsic(bcx, true, substs.type_at(0), llargs[0], llargs[1], llargs[2])
@@ -293,10 +269,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
             match int_type_width_signed(sty, ccx) {
                 Some((width, signed)) =>
                     match name {
-                        "ctlz" => count_zeros_intrinsic(bcx, &format!("llvm.ctlz.i{}", width),
-                                                        llargs[0]),
-                        "cttz" => count_zeros_intrinsic(bcx, &format!("llvm.cttz.i{}", width),
-                                                        llargs[0]),
+                        "ctlz" | "cttz" => {
+                            let y = C_bool(bcx.ccx(), false);
+                            let llfn = ccx.get_intrinsic(&format!("llvm.{}.i{}", name, width));
+                            bcx.call(llfn, &[llargs[0], y], None)
+                        }
                         "ctpop" => bcx.call(ccx.get_intrinsic(&format!("llvm.ctpop.i{}", width)),
                                         &llargs, None),
                         "bswap" => {
@@ -311,7 +288,16 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                             let intrinsic = format!("llvm.{}{}.with.overflow.i{}",
                                                     if signed { 's' } else { 'u' },
                                                     &name[..3], width);
-                            with_overflow_intrinsic(bcx, &intrinsic, llargs[0], llargs[1], llresult)
+                            let llfn = bcx.ccx().get_intrinsic(&intrinsic);
+
+                            // Convert `i1` to a `bool`, and write it to the out parameter
+                            let val = bcx.call(llfn, &[llargs[0], llargs[1]], None);
+                            let result = bcx.extract_value(val, 0);
+                            let overflow = bcx.zext(bcx.extract_value(val, 1), Type::bool(ccx));
+                            bcx.store(result, bcx.struct_gep(llresult, 0));
+                            bcx.store(overflow, bcx.struct_gep(llresult, 1));
+
+                            C_nil(bcx.ccx())
                         },
                         "overflowing_add" => bcx.add(llargs[0], llargs[1]),
                         "overflowing_sub" => bcx.sub(llargs[0], llargs[1]),
@@ -412,6 +398,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                 _ => ccx.sess().fatal("Atomic intrinsic not in correct format"),
             };
 
+            let invalid_monomorphization = |sty| {
+                span_invalid_monomorphization_error(tcx.sess, span,
+                    &format!("invalid monomorphization of `{}` intrinsic: \
+                              expected basic integer type, found `{}`", name, sty));
+            };
+
             match split[1] {
                 "cxchg" | "cxchgweak" => {
                     let sty = &substs.type_at(0).sty;
@@ -424,10 +416,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                         bcx.store(result, bcx.struct_gep(llresult, 0));
                         bcx.store(success, bcx.struct_gep(llresult, 1));
                     } else {
-                        span_invalid_monomorphization_error(
-                            tcx.sess, span,
-                            &format!("invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`", name, sty));
+                        invalid_monomorphization(sty);
                     }
                     C_nil(ccx)
                 }
@@ -437,10 +426,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                     if int_type_width_signed(sty, ccx).is_some() {
                         bcx.atomic_load(llargs[0], order)
                     } else {
-                        span_invalid_monomorphization_error(
-                            tcx.sess, span,
-                            &format!("invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`", name, sty));
+                        invalid_monomorphization(sty);
                         C_nil(ccx)
                     }
                 }
@@ -450,10 +436,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                     if int_type_width_signed(sty, ccx).is_some() {
                         bcx.atomic_store(llargs[1], llargs[0], order);
                     } else {
-                        span_invalid_monomorphization_error(
-                            tcx.sess, span,
-                            &format!("invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`", name, sty));
+                        invalid_monomorphization(sty);
                     }
                     C_nil(ccx)
                 }
@@ -489,15 +472,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                     if int_type_width_signed(sty, ccx).is_some() {
                         bcx.atomic_rmw(atom_op, llargs[0], llargs[1], order)
                     } else {
-                        span_invalid_monomorphization_error(
-                            tcx.sess, span,
-                            &format!("invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`", name, sty));
+                        invalid_monomorphization(sty);
                         C_nil(ccx)
                     }
                 }
             }
-
         }
 
         _ => {
@@ -529,18 +508,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                         *any_changes_needed |= llvm_elem.is_some();
 
                         let t = llvm_elem.as_ref().unwrap_or(t);
-                        let elem = one(ty_to_type(ccx, t,
-                                                  any_changes_needed));
+                        let elem = one(ty_to_type(ccx, t, any_changes_needed));
                         vec![elem.ptr_to()]
                     }
                     Vector(ref t, ref llvm_elem, length) => {
                         *any_changes_needed |= llvm_elem.is_some();
 
                         let t = llvm_elem.as_ref().unwrap_or(t);
-                        let elem = one(ty_to_type(ccx, t,
-                                                  any_changes_needed));
-                        vec![Type::vector(&elem,
-                                          length as u64)]
+                        let elem = one(ty_to_type(ccx, t, any_changes_needed));
+                        vec![Type::vector(&elem, length as u64)]
                     }
                     Aggregate(false, ref contents) => {
                         let elems = contents.iter()
@@ -585,8 +561,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
                     }
                     intrinsics::Type::Pointer(_, Some(ref llvm_elem), _) => {
                         let llvm_elem = one(ty_to_type(bcx.ccx(), llvm_elem, &mut false));
-                        vec![bcx.pointercast(llarg,
-                                         llvm_elem.ptr_to())]
+                        vec![bcx.pointercast(llarg, llvm_elem.ptr_to())]
                     }
                     intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
                         let llvm_elem = one(ty_to_type(bcx.ccx(), llvm_elem, &mut false));
@@ -718,33 +693,6 @@ fn memset_intrinsic<'blk, 'tcx>(
     call_memset(bcx, dst, val, bcx.mul(size, count), align, volatile)
 }
 
-fn count_zeros_intrinsic(bcx: &BlockAndBuilder,
-                         name: &str,
-                         val: ValueRef)
-                         -> ValueRef {
-    let y = C_bool(bcx.ccx(), false);
-    let llfn = bcx.ccx().get_intrinsic(&name);
-    bcx.call(llfn, &[val, y], None)
-}
-
-fn with_overflow_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
-                                       name: &str,
-                                       a: ValueRef,
-                                       b: ValueRef,
-                                       out: ValueRef)
-                                       -> ValueRef {
-    let llfn = bcx.ccx().get_intrinsic(&name);
-
-    // Convert `i1` to a `bool`, and write it to the out parameter
-    let val = bcx.call(llfn, &[a, b], None);
-    let result = bcx.extract_value(val, 0);
-    let overflow = bcx.zext(bcx.extract_value(val, 1), Type::bool(bcx.ccx()));
-    bcx.store(result, bcx.struct_gep(out, 0));
-    bcx.store(overflow, bcx.struct_gep(out, 1));
-
-    C_nil(bcx.ccx())
-}
-
 fn try_intrinsic<'blk, 'tcx>(
     bcx: &BlockAndBuilder<'blk, 'tcx>,
     func: ValueRef,