about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-07-07 16:14:00 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-07-07 17:54:58 +0200
commit16f82dce1c1c2a9f42a1a5e2c4e3345f07ee5c2d (patch)
tree36478e3287c19f6f6b8981b4a1e9ad78cb380af6 /src
parent3bdbf74d4703771571fdee1733b7b3d919b5ede8 (diff)
downloadrust-16f82dce1c1c2a9f42a1a5e2c4e3345f07ee5c2d.tar.gz
rust-16f82dce1c1c2a9f42a1a5e2c4e3345f07ee5c2d.zip
Clean up trans_arg_expr
As a preparation for implementing the temporary-move optimization for
argument passing. The optimization itself isn't in yet, since it
mysteriously corrupts memory.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs70
1 files changed, 25 insertions, 45 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index b89df1fe8da..487f79d661b 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5666,64 +5666,44 @@ fn trans_bind(&@block_ctxt cx, &@ast::expr f,
 
 fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
                   &@ast::expr e) -> result {
-    auto val;
-    auto bcx = cx;
-    auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e);
-    if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) {
-        auto re = trans_expr(bcx, e);
-        val = re.val;
-        bcx = re.bcx;
-    } else if (arg.mode != ty::mo_val) {
-        let lval_result lv;
-        if (ty::is_lval(e)) {
-            lv = trans_lval(bcx, e);
-        } else {
-            auto r = trans_expr(bcx, e);
-            if (type_is_immediate(cx.fcx.lcx.ccx, e_ty)) {
-                lv = lval_val(r.bcx, r.val);
-            } else { lv = lval_mem(r.bcx, r.val); }
-        }
-        bcx = lv.res.bcx;
-        if (lv.is_mem) {
-            val = lv.res.val;
-        } else {
-            // Non-mem but we're trying to alias; synthesize an
-            // alloca, spill to it and pass its address.
-            val = do_spill(lv.res.bcx, lv.res.val);
-        }
-    } else { auto re = trans_expr(bcx, e); val = re.val; bcx = re.bcx; }
-    auto is_bot = ty::type_is_bot(cx.fcx.lcx.ccx.tcx, e_ty);
-
-    // Make a copy here if the type is structural and we're passing by value.
-    if (arg.mode == ty::mo_val && !is_bot) {
-        if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, e_ty)) {
-            auto rslt = alloc_ty(bcx, e_ty);
-            bcx = rslt.bcx;
-            auto dst = rslt.val;
-            rslt = copy_val(bcx, INIT, dst, val, e_ty);
-            bcx = rslt.bcx;
-            val = dst;
-        } else {
-            bcx = copy_ty(bcx, val, e_ty).bcx;
-        }
-    }
-
+    auto ccx = cx.fcx.lcx.ccx;
+    auto e_ty = ty::expr_ty(ccx.tcx, e);
+    auto is_bot = ty::type_is_bot(ccx.tcx, e_ty);
+    auto lv = trans_lval(cx, e);
+    auto bcx = lv.res.bcx;
+    auto val = lv.res.val;
     if (is_bot) {
         // For values of type _|_, we generate an
         // "undef" value, as such a value should never
         // be inspected. It's important for the value
         // to have type lldestty0 (the callee's expected type).
         val = llvm::LLVMGetUndef(lldestty0);
-    } else if (ty::type_contains_params(cx.fcx.lcx.ccx.tcx, arg.ty)) {
+    } else if (arg.mode == ty::mo_val) {
+        if (ty::type_owns_heap_mem(ccx.tcx, e_ty)) {
+            auto dst = alloc_ty(bcx, e_ty);
+            val = dst.val;
+            bcx = move_val_if_temp(dst.bcx, INIT, val, lv, e_ty).bcx;
+        } else {
+            if (lv.is_mem) { val = load_if_immediate(bcx, val, e_ty); }
+            // FIXME for non-is-mem lvals, we should be able to just drop the
+            // cleanup. However, this currently leads to a memory-corrupting
+            // stage2/rustc . Find out why.
+            bcx = copy_ty(bcx, val, e_ty).bcx;
+        }
+    } else if (type_is_immediate(ccx, e_ty) && !lv.is_mem) {
+        val = do_spill(bcx, val);
+    }
+
+    if (!is_bot && ty::type_contains_params(ccx.tcx, arg.ty)) {
         auto lldestty = lldestty0;
         if (arg.mode == ty::mo_val
-            && ty::type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) {
+            && ty::type_is_structural(ccx.tcx, e_ty)) {
             lldestty = T_ptr(lldestty);
         }
         val = bcx.build.PointerCast(val, lldestty);
     }
     if (arg.mode == ty::mo_val
-        && ty::type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) {
+        && ty::type_is_structural(ccx.tcx, e_ty)) {
         // Until here we've been treating structures by pointer;
         // we are now passing it as an arg, so need to load it.
         val = bcx.build.Load(val);