Skip to content

Commit b4bae8f

Browse files
committed
Make vectors and strings immediates again
There's no good reason to force them to be spilled anymore. Some pieces of trans become more elegant this way, and less stack allocs and load/stores are needed. Issue #1021
1 parent 5c53959 commit b4bae8f

File tree

9 files changed

+100
-121
lines changed

9 files changed

+100
-121
lines changed

src/comp/front/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
284284
let args_ty: ast::ty = nospan(ast::ty_vec(args_mt));
285285

286286
let args_arg: ast::arg =
287-
{mode: ast::by_ref,
287+
{mode: ast::by_val,
288288
ty: @args_ty,
289289
ident: "args",
290290
id: cx.next_node_id()};

src/comp/middle/trans.rs

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,8 +1327,9 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
13271327
} else if ty::type_is_structural(bcx_tcx(bcx), t) {
13281328
bcx = iter_structural_ty(bcx, v, t, take_ty);
13291329
} else if ty::type_is_vec(bcx_tcx(bcx), t) {
1330-
bcx = tvec::duplicate(bcx, v);
1331-
bcx = tvec::iter_vec(bcx, v, t, take_ty);
1330+
let {bcx: cx, val} = tvec::duplicate(bcx, Load(bcx, v), t);
1331+
bcx = cx;
1332+
Store(bcx, val, v);
13321333
}
13331334

13341335
build_return(bcx);
@@ -1361,6 +1362,9 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
13611362
v = PointerCast(bcx, v, type_of_1(bcx, t));
13621363
trans_uniq::make_free_glue(bcx, v, t)
13631364
}
1365+
ty::ty_vec(_) | ty::ty_str. {
1366+
tvec::make_free_glue(bcx, PointerCast(bcx, v, type_of_1(bcx, t)), t)
1367+
}
13641368
ty::ty_obj(_) {
13651369
// Call through the obj's own fields-drop glue first.
13661370
// Then free the body.
@@ -1404,10 +1408,10 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) {
14041408
let ccx = bcx_ccx(bcx);
14051409
let bcx =
14061410
alt ty::struct(ccx.tcx, t) {
1407-
ty::ty_vec(_) { tvec::make_drop_glue(bcx, v0, t) }
1408-
ty::ty_str. { tvec::make_drop_glue(bcx, v0, t) }
14091411
ty::ty_box(_) { decr_refcnt_maybe_free(bcx, Load(bcx, v0), t) }
1410-
ty::ty_uniq(_) { free_ty(bcx, Load(bcx, v0), t) }
1412+
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str. {
1413+
free_ty(bcx, Load(bcx, v0), t)
1414+
}
14111415
ty::ty_obj(_) {
14121416
let box_cell =
14131417
GEP(bcx, v0, [C_int(0), C_int(abi::obj_field_box)]);
@@ -1958,8 +1962,10 @@ fn drop_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
19581962

19591963
fn drop_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
19601964
alt ty::struct(bcx_tcx(bcx), t) {
1965+
ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str. {
1966+
ret free_ty(bcx, v, t);
1967+
}
19611968
ty::ty_box(_) { ret decr_refcnt_maybe_free(bcx, v, t); }
1962-
ty::ty_uniq(_) { ret free_ty(bcx, v, t); }
19631969
// FIXME A ty_ptr pointing at something that needs drop glue is somehow
19641970
// marked as needing drop glue. This is probably a mistake.
19651971
ty::ty_ptr(_) { ret bcx; }
@@ -1973,6 +1979,7 @@ fn take_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
19731979
check trans_uniq::type_is_unique_box(bcx, t);
19741980
ret trans_uniq::duplicate(bcx, v, t);
19751981
}
1982+
ty::ty_str. | ty::ty_vec(_) { ret tvec::duplicate(bcx, v, t); }
19761983
_ { ret rslt(bcx, v); }
19771984
}
19781985
}
@@ -2068,30 +2075,32 @@ fn copy_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
20682075
ret copy_val_no_check(cx, action, dst, src, t);
20692076
}
20702077

2071-
fn copy_val_no_check(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2078+
fn copy_val_no_check(bcx: @block_ctxt, action: copy_action, dst: ValueRef,
20722079
src: ValueRef, t: ty::t) -> @block_ctxt {
2073-
let ccx = bcx_ccx(cx);
2080+
let ccx = bcx_ccx(bcx);
20742081
if ty::type_is_scalar(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t) {
2075-
Store(cx, src, dst);
2076-
ret cx;
2082+
Store(bcx, src, dst);
2083+
ret bcx;
20772084
}
2078-
if ty::type_is_nil(ccx.tcx, t) || ty::type_is_bot(ccx.tcx, t) { ret cx; }
2085+
if ty::type_is_nil(ccx.tcx, t) || ty::type_is_bot(ccx.tcx, t) { ret bcx; }
20792086
if ty::type_is_boxed(ccx.tcx, t) {
2080-
let bcx = cx;
2081-
if action == DROP_EXISTING { bcx = drop_ty(cx, dst, t); }
2087+
if action == DROP_EXISTING { bcx = drop_ty(bcx, dst, t); }
20822088
Store(bcx, src, dst);
20832089
ret take_ty(bcx, dst, t);
20842090
}
2091+
if ty::type_is_vec(ccx.tcx, t) {
2092+
if action == DROP_EXISTING { bcx = drop_ty(bcx, dst, t); }
2093+
let {bcx, val} = tvec::duplicate(bcx, src, t);
2094+
Store(bcx, val, dst);
2095+
ret bcx;
2096+
}
20852097
if ty::type_is_unique_box(ccx.tcx, t) {
2086-
let bcx = cx;
2087-
if action == DROP_EXISTING { bcx = drop_ty(cx, dst, t); }
2098+
if action == DROP_EXISTING { bcx = drop_ty(bcx, dst, t); }
20882099
check trans_uniq::type_is_unique_box(bcx, t);
20892100
ret trans_uniq::copy_val(bcx, dst, src, t);
20902101
}
2091-
if type_is_structural_or_param(ccx.tcx, t) || ty::type_is_vec(ccx.tcx, t)
2092-
{
2093-
let bcx = cx;
2094-
if action == DROP_EXISTING { bcx = drop_ty(cx, dst, t); }
2102+
if type_is_structural_or_param(ccx.tcx, t) {
2103+
if action == DROP_EXISTING { bcx = drop_ty(bcx, dst, t); }
20952104
bcx = memmove_ty(bcx, dst, src, t);
20962105
ret take_ty(bcx, dst, t);
20972106
}
@@ -2115,15 +2124,14 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
21152124
ret cx;
21162125
} else if ty::type_is_nil(tcx, t) || ty::type_is_bot(tcx, t) {
21172126
ret cx;
2118-
} else if ty::type_is_boxed(tcx, t) || ty::type_is_unique_box(tcx, t) {
2127+
} else if ty::type_is_boxed(tcx, t) || ty::type_is_unique(tcx, t) {
21192128
if src.kind == owned { src_val = Load(cx, src_val); }
21202129
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
21212130
Store(cx, src_val, dst);
21222131
if src.kind == owned { ret zero_alloca(cx, src.val, t); }
21232132
// If we're here, it must be a temporary.
21242133
ret revoke_clean(cx, src_val);
2125-
} else if ty::type_is_unique(tcx, t) ||
2126-
type_is_structural_or_param(tcx, t) {
2134+
} else if type_is_structural_or_param(tcx, t) {
21272135
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
21282136
cx = memmove_ty(cx, dst, src_val, t);
21292137
if src.kind == owned { ret zero_alloca(cx, src_val, t); }
@@ -2270,6 +2278,7 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
22702278
let upvars = get_freevars(ccx.tcx, id);
22712279
let env_r = build_closure(bcx, upvars, copying);
22722280
env = env_r.ptr;
2281+
bcx = env_r.bcx;
22732282
trans_closure(sub_cx, sp, f, llfn, none, [], id, {|fcx|
22742283
load_environment(bcx, fcx, env_r.ptrty, upvars, copying);
22752284
});
@@ -2600,14 +2609,13 @@ fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
26002609
let next_cx = new_sub_block_ctxt(cx, "next");
26012610
let seq_ty = ty::expr_ty(bcx_tcx(cx), seq);
26022611
let {bcx: bcx, val: seq} = trans_temp_expr(cx, seq);
2603-
let seq = PointerCast(bcx, seq, T_ptr(T_ptr(T_opaque_vec())));
2612+
let seq = PointerCast(bcx, seq, T_ptr(T_opaque_vec()));
26042613
let fill = tvec::get_fill(bcx, seq);
26052614
if ty::type_is_str(bcx_tcx(bcx), seq_ty) {
26062615
fill = Sub(bcx, fill, C_int(1));
26072616
}
2608-
let bcx =
2609-
tvec::iter_vec_raw(bcx, seq, seq_ty, fill,
2610-
bind inner(_, local, _, _, body, next_cx));
2617+
let bcx = tvec::iter_vec_raw(bcx, seq, seq_ty, fill,
2618+
bind inner(_, local, _, _, body, next_cx));
26112619
Br(bcx, next_cx.llbb);
26122620
ret next_cx;
26132621
}
@@ -3183,15 +3191,14 @@ fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr,
31833191
fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
31843192
id: ast::node_id) -> lval_result {
31853193
// Is this an interior vector?
3186-
31873194
let base_ty = ty::expr_ty(bcx_tcx(cx), base);
31883195
let exp = trans_temp_expr(cx, base);
31893196
let lv = autoderef(exp.bcx, exp.val, base_ty);
31903197
let ix = trans_temp_expr(lv.bcx, idx);
31913198
let v = lv.val;
31923199
let bcx = ix.bcx;
3193-
// Cast to an LLVM integer. Rust is less strict than LLVM in this regard.
31943200

3201+
// Cast to an LLVM integer. Rust is less strict than LLVM in this regard.
31953202
let ix_val;
31963203
let ix_size = llsize_of_real(bcx_ccx(cx), val_ty(ix.val));
31973204
let int_size = llsize_of_real(bcx_ccx(cx), T_int());
@@ -3200,6 +3207,7 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
32003207
} else if ix_size > int_size {
32013208
ix_val = Trunc(bcx, ix.val, T_int());
32023209
} else { ix_val = ix.val; }
3210+
32033211
let unit_ty = node_id_type(bcx_ccx(cx), id);
32043212
let unit_sz = size_of(bcx, unit_ty);
32053213
bcx = unit_sz.bcx;
@@ -4444,18 +4452,11 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
44444452
if kind == temporary {
44454453
revoke_clean(bcx, val);
44464454
*cell = val;
4447-
} else if kind == owned_imm {
4455+
} else if ty::type_is_immediate(bcx_tcx(bcx), ty) {
4456+
if kind == owned { val = Load(bcx, val); }
44484457
let {bcx: cx, val} = take_ty_immediate(bcx, val, ty);
44494458
*cell = val;
44504459
bcx = cx;
4451-
} else if ty::type_is_unique(bcx_tcx(bcx), ty) {
4452-
// FIXME make vectors immediate again, lose this hack
4453-
// Do a song and a dance to work around the fact that take_ty
4454-
// for unique boxes overwrites the pointer.
4455-
let oldval = Load(bcx, val);
4456-
bcx = take_ty(bcx, val, ty);
4457-
*cell = Load(bcx, val);
4458-
Store(bcx, oldval, val);
44594460
} else {
44604461
bcx = take_ty(bcx, val, ty);
44614462
*cell = Load(bcx, val);
@@ -5469,21 +5470,13 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
54695470
// If this argument to this function is a tag, it'll have come in to
54705471
// this function as an opaque blob due to the way that type_of()
54715472
// works. So we have to cast to the destination's view of the type.
5472-
5473-
let llargptr = alt fcx.llargs.find(va.id) {
5474-
some(local_mem(x)) { PointerCast(bcx, x, val_ty(lldestptr)) }
5475-
};
5473+
let llarg = alt fcx.llargs.find(va.id) { some(local_mem(x)) { x } };
54765474
let arg_ty = arg_tys[i].ty;
5477-
let llargval;
5478-
if ty::type_is_structural(cx.ccx.tcx, arg_ty) ||
5479-
ty::type_has_dynamic_size(cx.ccx.tcx, arg_ty) ||
5480-
(ty::type_is_unique(cx.ccx.tcx, arg_ty)
5481-
&& !ty::type_is_unique_box(cx.ccx.tcx, arg_ty)) {
5482-
// FIXME: Why do we do this for other unique pointer types but not
5483-
// unique boxes? Something's not quite right.
5484-
llargval = llargptr;
5485-
} else { llargval = Load(bcx, llargptr); }
5486-
bcx = copy_val(bcx, INIT, lldestptr, llargval, arg_ty);
5475+
if ty::type_contains_params(bcx_tcx(bcx), arg_ty) {
5476+
lldestptr = PointerCast(bcx, lldestptr, val_ty(llarg));
5477+
}
5478+
llarg = load_if_immediate(bcx, llarg, arg_ty);
5479+
bcx = copy_val(bcx, INIT, lldestptr, llarg, arg_ty);
54875480
i += 1u;
54885481
}
54895482
bcx = trans_block_cleanups(bcx, find_scope_cx(bcx));
@@ -5899,9 +5892,6 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
58995892
let i = arg_n;
59005893
for arg: ty::arg in args {
59015894
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
5902-
if arg.mode == ast::by_ref {
5903-
llarg = load_if_immediate(bcx, llarg, arg.ty);
5904-
}
59055895
assert (llarg as int != 0);
59065896
if cast_to_i32 {
59075897
let llarg_i32 = convert_arg_to_i32(bcx, llarg, arg.ty, arg.mode);

src/comp/middle/trans_alt.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
4949
alt l.node {
5050
ast::lit_str(s) {
5151
let strty = ty::mk_str(bcx_tcx(bcx));
52-
let {bcx, val: dst} = trans::alloc_ty(bcx, strty);
53-
bcx = trans_vec::trans_str(bcx, s, trans::save_in(dst));
54-
add_clean_temp(bcx, dst, strty);
55-
ret single_result(rslt(bcx, dst));
52+
let cell = trans::empty_dest_cell();
53+
bcx = trans_vec::trans_str(bcx, s, trans::by_val(cell));
54+
add_clean_temp(bcx, *cell, strty);
55+
ret single_result(rslt(bcx, *cell));
5656
}
5757
_ {
5858
ret single_result(
@@ -473,8 +473,9 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
473473
}
474474
lit(l) {
475475
kind = alt l.node {
476-
ast::lit_str(_) { compare }
477-
ast::lit_nil. { test_val = Load(bcx, val); compare }
476+
ast::lit_str(_) | ast::lit_nil. {
477+
test_val = Load(bcx, val); compare
478+
}
478479
_ { test_val = Load(bcx, val); switch }
479480
};
480481
}

0 commit comments

Comments
 (0)