Skip to content

Commit fd2321e

Browse files
committed
---
yaml --- r: 2073 b: refs/heads/master c: 7c55938 h: refs/heads/master i: 2071: c870a83 v: v3
1 parent ef6d9fc commit fd2321e

File tree

2 files changed

+74
-49
lines changed

2 files changed

+74
-49
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: f374fa44b6a1581a9723b9c91d76b5518fbea2e8
2+
refs/heads/master: 7c55938125ef06b57ffc2008610e56ed149fe544

trunk/src/comp/middle/trans.rs

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ fn declare_tydesc(@crate_ctxt cx, @ty.t t) {
15941594
}
15951595

15961596
auto glue_fn_ty = T_ptr(T_glue_fn(cx.tn));
1597-
1597+
15981598
auto name = sanitize(cx.names.next("tydesc_" + ty.ty_to_str(t)));
15991599
auto gvar = llvm.LLVMAddGlobal(cx.llmod, T_tydesc(cx.tn),
16001600
_str.buf(name));
@@ -1655,13 +1655,17 @@ fn make_generic_glue(@crate_ctxt cx, @ty.t t, ValueRef llfn,
16551655

16561656
auto re;
16571657
if (!ty.type_is_scalar(t)) {
1658+
1659+
// Any nontrivial glue is with values passed *by alias*; this is a
1660+
// requirement since in many contexts glue is invoked indirectly and
1661+
// the caller has no idea if it's dealing with something that can be
1662+
// passed by value.
1663+
16581664
auto llty;
16591665
if (ty.type_has_dynamic_size(t)) {
16601666
llty = T_ptr(T_i8());
1661-
} else if (ty.type_is_structural(t)) {
1662-
llty = T_ptr(type_of(cx, t));
16631667
} else {
1664-
llty = type_of(cx, t);
1668+
llty = T_ptr(type_of(cx, t));
16651669
}
16661670

16671671
auto lltyparams = llvm.LLVMGetParam(llfn, 3u);
@@ -1690,8 +1694,9 @@ fn make_generic_glue(@crate_ctxt cx, @ty.t t, ValueRef llfn,
16901694
}
16911695

16921696
fn make_take_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
1697+
// NB: v is an *alias* of type t here, not a direct value.
16931698
if (ty.type_is_boxed(t)) {
1694-
ret incr_refcnt_of_boxed(cx, v);
1699+
ret incr_refcnt_of_boxed(cx, cx.build.Load(v));
16951700

16961701
} else if (ty.type_is_structural(t)) {
16971702
ret iter_structural_ty(cx, v, t,
@@ -1719,9 +1724,11 @@ fn incr_refcnt_of_boxed(@block_ctxt cx, ValueRef box_ptr) -> result {
17191724
ret res(next_cx, C_nil());
17201725
}
17211726

1722-
fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
1727+
fn make_drop_glue(@block_ctxt cx, ValueRef v0, @ty.t t) -> result {
1728+
// NB: v0 is an *alias* of type t here, not a direct value.
17231729
alt (t.struct) {
17241730
case (ty.ty_str) {
1731+
auto v = cx.build.Load(v0);
17251732
ret decr_refcnt_and_if_zero
17261733
(cx, v, bind trans_non_gc_free(_, v),
17271734
"free string",
@@ -1736,6 +1743,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
17361743
// FIXME: switch gc/non-gc on layer of the type.
17371744
ret trans_non_gc_free(res.bcx, v);
17381745
}
1746+
auto v = cx.build.Load(v0);
17391747
ret decr_refcnt_and_if_zero(cx, v,
17401748
bind hit_zero(_, v, t),
17411749
"free vector",
@@ -1749,11 +1757,12 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
17491757
vec(C_int(0),
17501758
C_int(abi.box_rc_field_body)));
17511759

1752-
auto body_val = load_scalar_or_boxed(cx, body, body_ty);
1760+
auto body_val = load_if_immediate(cx, body, body_ty);
17531761
auto res = drop_ty(cx, body_val, body_ty);
17541762
// FIXME: switch gc/non-gc on layer of the type.
17551763
ret trans_non_gc_free(res.bcx, v);
17561764
}
1765+
auto v = cx.build.Load(v0);
17571766
ret decr_refcnt_and_if_zero(cx, v,
17581767
bind hit_zero(_, v, body_mt.ty),
17591768
"free box",
@@ -1765,6 +1774,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
17651774
ret trans_upcall(cx, "upcall_del_port",
17661775
vec(vp2i(cx, v)));
17671776
}
1777+
auto v = cx.build.Load(v0);
17681778
ret decr_refcnt_and_if_zero(cx, v,
17691779
bind hit_zero(_, v),
17701780
"free port",
@@ -1776,6 +1786,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
17761786
ret trans_upcall(cx, "upcall_del_chan",
17771787
vec(vp2i(cx, v)));
17781788
}
1789+
auto v = cx.build.Load(v0);
17791790
ret decr_refcnt_and_if_zero(cx, v,
17801791
bind hit_zero(_, v),
17811792
"free chan",
@@ -1804,7 +1815,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
18041815
ret trans_non_gc_free(cx, v);
18051816
}
18061817
auto box_cell =
1807-
cx.build.GEP(v,
1818+
cx.build.GEP(v0,
18081819
vec(C_int(0),
18091820
C_int(abi.obj_field_box)));
18101821

@@ -1843,7 +1854,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
18431854
ret trans_non_gc_free(cx, v);
18441855
}
18451856
auto box_cell =
1846-
cx.build.GEP(v,
1857+
cx.build.GEP(v0,
18471858
vec(C_int(0),
18481859
C_int(abi.fn_field_box)));
18491860

@@ -1857,7 +1868,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
18571868

18581869
case (_) {
18591870
if (ty.type_is_structural(t)) {
1860-
ret iter_structural_ty(cx, v, t,
1871+
ret iter_structural_ty(cx, v0, t,
18611872
bind drop_ty(_, _, _));
18621873

18631874
} else if (ty.type_is_scalar(t) ||
@@ -2039,8 +2050,8 @@ fn iter_structural_ty_full(@block_ctxt cx,
20392050
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
20402051
auto elt_b = r.val;
20412052
r = f(r.bcx,
2042-
load_scalar_or_boxed(r.bcx, elt_a, arg.ty),
2043-
load_scalar_or_boxed(r.bcx, elt_b, arg.ty),
2053+
load_if_immediate(r.bcx, elt_a, arg.ty),
2054+
load_if_immediate(r.bcx, elt_b, arg.ty),
20442055
arg.ty);
20452056
i += 1;
20462057
}
@@ -2053,8 +2064,8 @@ fn iter_structural_ty_full(@block_ctxt cx,
20532064
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
20542065
auto llfld_b = r.val;
20552066
r = f(r.bcx,
2056-
load_scalar_or_boxed(r.bcx, llfld_a, fld.mt.ty),
2057-
load_scalar_or_boxed(r.bcx, llfld_b, fld.mt.ty),
2067+
load_if_immediate(r.bcx, llfld_a, fld.mt.ty),
2068+
load_if_immediate(r.bcx, llfld_b, fld.mt.ty),
20582069
fld.mt.ty);
20592070
i += 1;
20602071
}
@@ -2126,12 +2137,12 @@ fn iter_structural_ty_full(@block_ctxt cx,
21262137
ty_params, tps, a.ty);
21272138

21282139
auto llfld_a =
2129-
load_scalar_or_boxed(variant_cx,
2140+
load_if_immediate(variant_cx,
21302141
llfldp_a,
21312142
ty_subst);
21322143

21332144
auto llfld_b =
2134-
load_scalar_or_boxed(variant_cx,
2145+
load_if_immediate(variant_cx,
21352146
llfldp_b,
21362147
ty_subst);
21372148

@@ -2252,7 +2263,7 @@ fn iter_sequence_inner(@block_ctxt cx,
22522263
}
22532264

22542265
auto p = cx.build.PointerCast(src, llptrty);
2255-
ret f(cx, load_scalar_or_boxed(cx, p, elt_ty), elt_ty);
2266+
ret f(cx, load_if_immediate(cx, p, elt_ty), elt_ty);
22562267
}
22572268

22582269
auto elt_sz = size_of(cx, elt_ty);
@@ -2333,12 +2344,12 @@ fn call_tydesc_glue_full(@block_ctxt cx, ValueRef v,
23332344

23342345
fn call_tydesc_glue(@block_ctxt cx, ValueRef v, @ty.t t, int field) {
23352346
auto td = get_tydesc(cx, t);
2336-
call_tydesc_glue_full(td.bcx, v, td.val, field);
2347+
call_tydesc_glue_full(td.bcx,
2348+
spill_if_immediate(td.bcx, v, t),
2349+
td.val, field);
23372350
}
23382351

2339-
fn take_ty(@block_ctxt cx,
2340-
ValueRef v,
2341-
@ty.t t) -> result {
2352+
fn take_ty(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
23422353
if (!ty.type_is_scalar(t)) {
23432354
call_tydesc_glue(cx, v, t, abi.tydesc_field_take_glue);
23442355
}
@@ -2348,7 +2359,7 @@ fn take_ty(@block_ctxt cx,
23482359
fn drop_slot(@block_ctxt cx,
23492360
ValueRef slot,
23502361
@ty.t t) -> result {
2351-
auto llptr = load_scalar_or_boxed(cx, slot, t);
2362+
auto llptr = load_if_immediate(cx, slot, t);
23522363
auto re = drop_ty(cx, llptr, t);
23532364

23542365
auto llty = val_ty(slot);
@@ -2692,8 +2703,8 @@ fn trans_compare(@block_ctxt cx0, ast.binop op, @ty.t t0,
26922703
auto av = av0;
26932704
auto bv = bv0;
26942705
if (load_inner) {
2695-
av = load_scalar_or_boxed(cx, av, t);
2696-
bv = load_scalar_or_boxed(cx, bv, t);
2706+
av = load_if_immediate(cx, av, t);
2707+
bv = load_if_immediate(cx, bv, t);
26972708
}
26982709

26992710
// First 'eq' comparison: if so, continue to next elts.
@@ -2839,7 +2850,7 @@ fn trans_vec_add(@block_ctxt cx, @ty.t t,
28392850
auto tmp = r.val;
28402851
r = copy_ty(r.bcx, INIT, tmp, lhs, t);
28412852
auto bcx = trans_vec_append(r.bcx, t, tmp, rhs).bcx;
2842-
tmp = load_scalar_or_boxed(bcx, tmp, t);
2853+
tmp = load_if_immediate(bcx, tmp, t);
28432854
find_scope_cx(cx).cleanups +=
28442855
vec(clean(bind drop_ty(_, tmp, t)));
28452856
ret res(bcx, tmp);
@@ -2946,7 +2957,7 @@ fn autoderef(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
29462957
v1 = body;
29472958
}
29482959

2949-
v1 = load_scalar_or_boxed(cx, v1, t1);
2960+
v1 = load_if_immediate(cx, v1, t1);
29502961
}
29512962
case (_) {
29522963
ret res(cx, v1);
@@ -3495,7 +3506,7 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
34953506
auto llsubvalptr = rslt.val;
34963507
matched_cx = rslt.bcx;
34973508

3498-
auto llsubval = load_scalar_or_boxed(matched_cx,
3509+
auto llsubval = load_if_immediate(matched_cx,
34993510
llsubvalptr,
35003511
pat_ty(subpat));
35013512
auto subpat_res = trans_pat_match(matched_cx, subpat,
@@ -3550,7 +3561,7 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
35503561
this_cx = rslt.bcx;
35513562
auto llsubvalptr = rslt.val;
35523563

3553-
auto llsubval = load_scalar_or_boxed(this_cx, llsubvalptr,
3564+
auto llsubval = load_if_immediate(this_cx, llsubvalptr,
35543565
pat_ty(subpat));
35553566
auto subpat_res = trans_pat_binding(this_cx, subpat,
35563567
llsubval);
@@ -4417,10 +4428,7 @@ fn trans_args(@block_ctxt cx,
44174428
} else {
44184429
// Non-mem but we're trying to alias; synthesize an
44194430
// alloca, spill to it and pass its address.
4420-
auto llty = val_ty(lv.res.val);
4421-
auto llptr = alloca(lv.res.bcx, llty);
4422-
lv.res.bcx.build.Store(lv.res.val, llptr);
4423-
val = llptr;
4431+
val = do_spill(lv.res.bcx, lv.res.val);
44244432
}
44254433

44264434
} else {
@@ -4496,7 +4504,7 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
44964504
// self-call
44974505
fn_ty = meth;
44984506
}
4499-
4507+
45004508
case (_) {
45014509
fn_ty = ty.expr_ty(f);
45024510

@@ -4527,7 +4535,7 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
45274535
auto retval = C_nil();
45284536

45294537
if (!ty.type_is_nil(ret_ty)) {
4530-
retval = load_scalar_or_boxed(bcx, llretslot, ret_ty);
4538+
retval = load_if_immediate(bcx, llretslot, ret_ty);
45314539
// Retval doesn't correspond to anything really tangible in the frame,
45324540
// but it's a ref all the same, so we put a note here to drop it when
45334541
// we're done in this scope.
@@ -4680,7 +4688,7 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
46804688
if (!expr_provided) {
46814689
src_res = GEP_tup_like(bcx, t, base_val, vec(0, i));
46824690
src_res = res(src_res.bcx,
4683-
load_scalar_or_boxed(bcx, src_res.val, e_ty));
4691+
load_if_immediate(bcx, src_res.val, e_ty));
46844692
}
46854693

46864694
bcx = src_res.bcx;
@@ -4757,7 +4765,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
47574765
auto t = node_ann_type(cx.fcx.ccx, ann);
47584766
auto lhs_res = trans_lval(cx, dst);
47594767
check (lhs_res.is_mem);
4760-
auto lhs_val = load_scalar_or_boxed(lhs_res.res.bcx,
4768+
auto lhs_val = load_if_immediate(lhs_res.res.bcx,
47614769
lhs_res.res.val, t);
47624770
auto rhs_res = trans_expr(lhs_res.res.bcx, src);
47634771
auto v = trans_eager_binop(rhs_res.bcx, op, t,
@@ -4853,21 +4861,38 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
48534861

48544862
auto t = ty.expr_ty(e);
48554863
auto sub = trans_lval(cx, e);
4856-
ret res(sub.res.bcx, load_scalar_or_boxed(sub.res.bcx, sub.res.val, t));
4864+
ret res(sub.res.bcx, load_if_immediate(sub.res.bcx, sub.res.val, t));
48574865
}
48584866

48594867
// We pass structural values around the compiler "by pointer" and
4860-
// non-structural values (scalars and boxes) "by value". This function selects
4861-
// whether to load a pointer or pass it.
4868+
// non-structural values (scalars, boxes, pointers) "by value". We call the
4869+
// latter group "immediates" and, in some circumstances when we know we have a
4870+
// pointer (or need one), perform load/store operations based on the
4871+
// immediate-ness of the type.
4872+
4873+
fn type_is_immediate(@ty.t t) -> bool {
4874+
ret ty.type_is_scalar(t) || ty.type_is_boxed(t) || ty.type_is_native(t);
4875+
}
4876+
4877+
fn do_spill(@block_ctxt cx, ValueRef v) -> ValueRef {
4878+
// We have a value but we have to spill it to pass by alias.
4879+
auto llptr = alloca(cx, val_ty(v));
4880+
cx.build.Store(v, llptr);
4881+
ret llptr;
4882+
}
48624883

4863-
fn load_scalar_or_boxed(@block_ctxt cx,
4864-
ValueRef v,
4865-
@ty.t t) -> ValueRef {
4866-
if (ty.type_is_scalar(t) || ty.type_is_boxed(t) || ty.type_is_native(t)) {
4884+
fn spill_if_immediate(@block_ctxt cx, ValueRef v, @ty.t t) -> ValueRef {
4885+
if (type_is_immediate(t)) {
4886+
ret do_spill(cx, v);
4887+
}
4888+
ret v;
4889+
}
4890+
4891+
fn load_if_immediate(@block_ctxt cx, ValueRef v, @ty.t t) -> ValueRef {
4892+
if (type_is_immediate(t)) {
48674893
ret cx.build.Load(v);
4868-
} else {
4869-
ret v;
48704894
}
4895+
ret v;
48714896
}
48724897

48734898
fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
@@ -5180,7 +5205,7 @@ fn recv_val(@block_ctxt cx, ValueRef lhs, @ast.expr rhs,
51805205
vp2i(bcx, prt.val)));
51815206
bcx = sub.bcx;
51825207

5183-
auto data_load = load_scalar_or_boxed(bcx, lhs, unit_ty);
5208+
auto data_load = load_if_immediate(bcx, lhs, unit_ty);
51845209
auto cp = copy_ty(bcx, action, lhs, data_load, unit_ty);
51855210
bcx = cp.bcx;
51865211

@@ -5437,7 +5462,7 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
54375462
fn drop_hoisted_ty(@block_ctxt cx,
54385463
ValueRef alloca_val,
54395464
@ty.t t) -> result {
5440-
auto reg_val = load_scalar_or_boxed(cx,
5465+
auto reg_val = load_if_immediate(cx,
54415466
alloca_val, t);
54425467
ret drop_ty(cx, reg_val, t);
54435468
}
@@ -5881,7 +5906,7 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
58815906
i = 0;
58825907
for (ast.obj_field f in ob.fields) {
58835908
auto arg = bcx.fcx.llargs.get(f.id);
5884-
arg = load_scalar_or_boxed(bcx, arg, arg_tys.(i).ty);
5909+
arg = load_if_immediate(bcx, arg, arg_tys.(i).ty);
58855910
auto field = GEP_tup_like(bcx, fields_ty, body_fields.val,
58865911
vec(0, i));
58875912
bcx = field.bcx;

0 commit comments

Comments
 (0)