about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2015-05-30 01:23:29 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2015-06-02 10:37:45 +0200
commit528ab1fe9b51228daf41c7110216c33a93cfa341 (patch)
treee246af2c48cb440aff0e223a0b542a225b6f9737
parent3e561f05c00cd180ec02db4ccab2840a4aba93d2 (diff)
downloadrust-528ab1fe9b51228daf41c7110216c33a93cfa341.tar.gz
rust-528ab1fe9b51228daf41c7110216c33a93cfa341.zip
Hack the move_val_init intrinsic to trans directly into the destination address.
remove dead code further down for intrinsic.
-rw-r--r--src/librustc_trans/trans/intrinsic.rs58
1 files changed, 42 insertions, 16 deletions
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index f64cc29a2fb..4a7268f5dfe 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -265,6 +265,48 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
     }
 
+    // For `move_val_init` we can evaluate the destination address
+    // (the first argument) and then trans the source value (the
+    // second argument) directly into the resulting destination
+    // address.
+    if &name[..] == "move_val_init" {
+        if let callee::ArgExprs(ref exprs) = args {
+            let (dest_expr, source_expr) = if exprs.len() != 2 {
+                ccx.sess().bug("expected two exprs as arguments for `move_val_init` intrinsic");
+            } else {
+                (&exprs[0], &exprs[1])
+            };
+            let arg_tys = ty::erase_late_bound_regions(bcx.tcx(), &ty::ty_fn_args(callee_ty));
+
+            // evaluate destination address
+            let lldest_addr = unpack_result!(bcx, {
+                let dest_datum = unpack_datum!(bcx, expr::trans(bcx, dest_expr));
+                callee::trans_arg_datum(bcx,
+                                        arg_tys[0],
+                                        dest_datum,
+                                        cleanup::CustomScope(cleanup_scope),
+                                        callee::DontAutorefArg)
+            });
+
+            // `expr::trans_into(bcx, expr, dest)` is equiv to
+            //
+            //    `trans(bcx, expr).store_to_dest(dest)`,
+            //
+            // which for `dest == expr::SaveIn(addr)`, is equivalent to:
+            //
+            //    `trans(bcx, expr).store_to(bcx, addr)`.
+            let lldest = expr::Dest::SaveIn(lldest_addr);
+            bcx = expr::trans_into(bcx, source_expr, lldest);
+
+            let llresult = C_nil(ccx);
+            fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
+
+            return Result::new(bcx, llresult);
+        } else {
+            ccx.sess().bug("expected two exprs as arguments for `move_val_init` intrinsic");
+        }
+    }
+
     // Push the arguments.
     let mut llargs = Vec::new();
     bcx = callee::trans_args(bcx,
@@ -356,22 +398,6 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             let lltp_ty = type_of::type_of(ccx, tp_ty);
             C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))
         }
-        (_, "move_val_init") => {
-            // Create a datum reflecting the value being moved.
-            // Use `appropriate_mode` so that the datum is by ref
-            // if the value is non-immediate. Note that, with
-            // intrinsics, there are no argument cleanups to
-            // concern ourselves with, so we can use an rvalue datum.
-            let tp_ty = *substs.types.get(FnSpace, 0);
-            let mode = appropriate_rvalue_mode(ccx, tp_ty);
-            let src = Datum {
-                val: llargs[1],
-                ty: tp_ty,
-                kind: Rvalue::new(mode)
-            };
-            bcx = src.store_to(bcx, llargs[0]);
-            C_nil(ccx)
-        }
         (_, "drop_in_place") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
             glue::drop_ty(bcx, llargs[0], tp_ty, call_debug_location);