about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-26 11:25:53 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-26 11:25:53 -0700
commit62be878ed1715650f080c3b113a85f73e7af0973 (patch)
tree0a12c897a43476a216485411bfca1bb91ae6a13d
parentff9151fa55e4e81c0cbaa7181eb672b2df6b53f6 (diff)
downloadrust-62be878ed1715650f080c3b113a85f73e7af0973.tar.gz
rust-62be878ed1715650f080c3b113a85f73e7af0973.zip
rustc: Use memmove in unsafe::reinterpret_cast (issue #3025).
This was causing a bunch of structural copies, which when inlined
was leading to enormous register pressure. Often this is seen in
code which makes use of result::unwrap.
-rw-r--r--src/rustc/middle/trans/foreign.rs9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs
index 5cbdae9c076..d7cc5e9139a 100644
--- a/src/rustc/middle/trans/foreign.rs
+++ b/src/rustc/middle/trans/foreign.rs
@@ -937,9 +937,12 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
                          ty_to_str(ccx.tcx, substs.tys[1]), out_sz));
         }
         if !ty::type_is_nil(substs.tys[1]) {
-            let cast = PointerCast(bcx, get_param(decl, first_real_arg),
-                                   T_ptr(llout_ty));
-            Store(bcx, Load(bcx, cast), fcx.llretptr);
+            // NB: Do not use a Load and Store here. This causes massive code
+            // bloat when reinterpret_cast is used on large structural types.
+            let llretptr = PointerCast(bcx, fcx.llretptr, T_ptr(T_i8()));
+            let llcast = get_param(decl, first_real_arg);
+            let llcast = PointerCast(bcx, llcast, T_ptr(T_i8()));
+            call_memmove(bcx, llretptr, llcast, llsize_of(ccx, lltp_ty));
         }
       }
       ~"addr_of" => {