Skip to content

Commit 5030aad

Browse files
committed
---
yaml --- r: 5567 b: refs/heads/master c: 8282f7f h: refs/heads/master i: 5565: e9a8895 5563: 9d17303 5559: b947836 5551: a2a0aaa 5535: c7aa08f 5503: 530c233 v: v3
1 parent b1f7883 commit 5030aad

File tree

4 files changed

+116
-124
lines changed

4 files changed

+116
-124
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: 806e74fbf50febd4509a61dac9abcb7c9c4efd86
2+
refs/heads/master: 8282f7fe805087f26ed60a6a5cba0abe50637d39

trunk/src/comp/middle/trans.rs

Lines changed: 91 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,10 +2158,7 @@ fn trans_lit(cx: @block_ctxt, lit: ast::lit, dest: dest) -> @block_ctxt {
21582158
alt lit.node {
21592159
ast::lit_str(s) { ret tvec::trans_str(cx, s, dest); }
21602160
_ {
2161-
let cell = alt dest { by_val(c) { c }
2162-
_ { bcx_ccx(cx).sess.span_note(lit.span, "here"); fail; }};
2163-
*cell = trans_crate_lit(bcx_ccx(cx), lit);
2164-
ret cx;
2161+
ret store_in_dest(cx, trans_crate_lit(bcx_ccx(cx), lit), dest);
21652162
}
21662163
}
21672164
}
@@ -2253,8 +2250,9 @@ fn trans_compare(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
22532250
// Important to get types for both lhs and rhs, because one might be _|_
22542251
// and the other not.
22552252
fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
2256-
lhs_t: ty::t, rhs: ValueRef, rhs_t: ty::t) -> result {
2257-
2253+
lhs_t: ty::t, rhs: ValueRef, rhs_t: ty::t, dest: dest)
2254+
-> @block_ctxt {
2255+
if dest == ignore { ret cx; }
22582256
let is_float = false;
22592257
let intype = lhs_t;
22602258
if ty::type_is_bot(bcx_tcx(cx), intype) { intype = rhs_t; }
@@ -2263,45 +2261,47 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
22632261
ty::ty_float. { is_float = true; }
22642262
_ { is_float = false; }
22652263
}
2266-
alt op {
2264+
if op == ast::add && ty::type_is_sequence(bcx_tcx(cx), intype) {
2265+
ret tvec::trans_add(cx, intype, lhs, rhs, dest);
2266+
}
2267+
let val = alt op {
22672268
ast::add. {
2268-
if ty::type_is_sequence(bcx_tcx(cx), intype) {
2269-
ret tvec::trans_add(cx, intype, lhs, rhs);
2270-
}
2271-
if is_float {
2272-
ret rslt(cx, FAdd(cx, lhs, rhs));
2273-
} else { ret rslt(cx, Add(cx, lhs, rhs)); }
2269+
if is_float { FAdd(cx, lhs, rhs) }
2270+
else { Add(cx, lhs, rhs) }
22742271
}
22752272
ast::sub. {
2276-
if is_float {
2277-
ret rslt(cx, FSub(cx, lhs, rhs));
2278-
} else { ret rslt(cx, Sub(cx, lhs, rhs)); }
2273+
if is_float { FSub(cx, lhs, rhs) }
2274+
else { Sub(cx, lhs, rhs) }
22792275
}
22802276
ast::mul. {
2281-
if is_float {
2282-
ret rslt(cx, FMul(cx, lhs, rhs));
2283-
} else { ret rslt(cx, Mul(cx, lhs, rhs)); }
2277+
if is_float { FMul(cx, lhs, rhs) }
2278+
else { Mul(cx, lhs, rhs) }
22842279
}
22852280
ast::div. {
2286-
if is_float { ret rslt(cx, FDiv(cx, lhs, rhs)); }
2287-
if ty::type_is_signed(bcx_tcx(cx), intype) {
2288-
ret rslt(cx, SDiv(cx, lhs, rhs));
2289-
} else { ret rslt(cx, UDiv(cx, lhs, rhs)); }
2281+
if is_float { FDiv(cx, lhs, rhs) }
2282+
else if ty::type_is_signed(bcx_tcx(cx), intype) {
2283+
SDiv(cx, lhs, rhs)
2284+
} else { UDiv(cx, lhs, rhs) }
22902285
}
22912286
ast::rem. {
2292-
if is_float { ret rslt(cx, FRem(cx, lhs, rhs)); }
2293-
if ty::type_is_signed(bcx_tcx(cx), intype) {
2294-
ret rslt(cx, SRem(cx, lhs, rhs));
2295-
} else { ret rslt(cx, URem(cx, lhs, rhs)); }
2287+
if is_float { FRem(cx, lhs, rhs) }
2288+
else if ty::type_is_signed(bcx_tcx(cx), intype) {
2289+
SRem(cx, lhs, rhs)
2290+
} else { URem(cx, lhs, rhs) }
2291+
}
2292+
ast::bitor. { Or(cx, lhs, rhs) }
2293+
ast::bitand. { And(cx, lhs, rhs) }
2294+
ast::bitxor. { Xor(cx, lhs, rhs) }
2295+
ast::lsl. { Shl(cx, lhs, rhs) }
2296+
ast::lsr. { LShr(cx, lhs, rhs) }
2297+
ast::asr. { AShr(cx, lhs, rhs) }
2298+
_ {
2299+
let cmpr = trans_compare(cx, op, lhs, lhs_t, rhs, rhs_t);
2300+
cx = cmpr.bcx;
2301+
cmpr.val
22962302
}
2297-
ast::bitor. { ret rslt(cx, Or(cx, lhs, rhs)); }
2298-
ast::bitand. { ret rslt(cx, And(cx, lhs, rhs)); }
2299-
ast::bitxor. { ret rslt(cx, Xor(cx, lhs, rhs)); }
2300-
ast::lsl. { ret rslt(cx, Shl(cx, lhs, rhs)); }
2301-
ast::lsr. { ret rslt(cx, LShr(cx, lhs, rhs)); }
2302-
ast::asr. { ret rslt(cx, AShr(cx, lhs, rhs)); }
2303-
_ { ret trans_compare(cx, op, lhs, lhs_t, rhs, rhs_t); }
2304-
}
2303+
};
2304+
ret store_in_dest(cx, val, dest);
23052305
}
23062306

23072307
fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
@@ -2334,11 +2334,8 @@ fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
23342334
}
23352335
}
23362336
let lhs_val = load_if_immediate(rhs_res.bcx, lhs_res.val, t);
2337-
let v = trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t);
2338-
// FIXME: calculate copy init-ness in typestate.
2339-
// This is always a temporary, so can always be safely moved
2340-
ret move_val(v.bcx, DROP_EXISTING, lhs_res.val,
2341-
lval_val(v.bcx, v.val), t);
2337+
ret trans_eager_binop(rhs_res.bcx, op, lhs_val, t, rhs_res.val, t,
2338+
overwrite(lhs_res.val, t));
23422339
}
23432340

23442341
fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t {
@@ -2390,84 +2387,55 @@ fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t {
23902387
ret {bcx: cx, val: v1, ty: t1};
23912388
}
23922389

2393-
fn trans_binary(cx: @block_ctxt, op: ast::binop, a: @ast::expr, b: @ast::expr)
2394-
-> result {
2390+
fn trans_lazy_binop(bcx: @block_ctxt, op: ast::binop, a: @ast::expr,
2391+
b: @ast::expr, dest: dest) -> @block_ctxt {
2392+
let is_and = alt op { ast::and. { true } ast::or. { false } };
2393+
let lhs_res = trans_expr(bcx, a);
2394+
if lhs_res.bcx.unreachable { ret lhs_res.bcx; }
2395+
let rhs_cx = new_scope_block_ctxt(lhs_res.bcx, "rhs");
2396+
let rhs_res = trans_expr(rhs_cx, b);
2397+
2398+
let lhs_past_cx = new_scope_block_ctxt(lhs_res.bcx, "lhs");
2399+
// The following line ensures that any cleanups for rhs
2400+
// are done within the block for rhs. This is necessary
2401+
// because and/or are lazy. So the rhs may never execute,
2402+
// and the cleanups can't be pushed into later code.
2403+
let rhs_bcx = trans_block_cleanups(rhs_res.bcx, rhs_cx);
2404+
if is_and {
2405+
CondBr(lhs_res.bcx, lhs_res.val, rhs_cx.llbb, lhs_past_cx.llbb);
2406+
} else {
2407+
CondBr(lhs_res.bcx, lhs_res.val, lhs_past_cx.llbb, rhs_cx.llbb);
2408+
}
23952409

2410+
let join_cx = new_sub_block_ctxt(bcx, "join");
2411+
Br(lhs_past_cx, join_cx.llbb);
2412+
if rhs_bcx.unreachable {
2413+
ret store_in_dest(join_cx, C_bool(!is_and), dest);
2414+
}
2415+
Br(rhs_bcx, join_cx.llbb);
2416+
let phi = Phi(join_cx, T_bool(), [C_bool(!is_and), rhs_res.val],
2417+
[lhs_past_cx.llbb, rhs_bcx.llbb]);
2418+
ret store_in_dest(join_cx, phi, dest);
2419+
}
2420+
2421+
fn trans_binary(cx: @block_ctxt, op: ast::binop, a: @ast::expr, b: @ast::expr,
2422+
dest: dest) -> @block_ctxt {
23962423
// First couple cases are lazy:
23972424
alt op {
2398-
ast::and. {
2399-
// Lazy-eval and
2400-
let lhs_res = trans_expr(cx, a);
2401-
let rhs_cx = new_scope_block_ctxt(lhs_res.bcx, "rhs");
2402-
let rhs_res = trans_expr(rhs_cx, b);
2403-
2404-
let lhs_false_cx = new_scope_block_ctxt(lhs_res.bcx, "lhs false");
2405-
let lhs_false_res = rslt(lhs_false_cx, C_bool(false));
2406-
2407-
// The following line ensures that any cleanups for rhs
2408-
// are done within the block for rhs. This is necessary
2409-
// because and/or are lazy. So the rhs may never execute,
2410-
// and the cleanups can't be pushed into later code.
2411-
let rhs_bcx = trans_block_cleanups(rhs_res.bcx, rhs_cx);
2412-
CondBr(lhs_res.bcx, lhs_res.val, rhs_cx.llbb, lhs_false_cx.llbb);
2413-
ret join_results(cx, T_bool(),
2414-
[lhs_false_res, {bcx: rhs_bcx, val: rhs_res.val}]);
2415-
}
2416-
ast::or. {
2417-
// Lazy-eval or
2418-
let lhs_res = trans_expr(cx, a);
2419-
let rhs_cx = new_scope_block_ctxt(lhs_res.bcx, "rhs");
2420-
let rhs_res = trans_expr(rhs_cx, b);
2421-
let lhs_true_cx = new_scope_block_ctxt(lhs_res.bcx, "lhs true");
2422-
let lhs_true_res = rslt(lhs_true_cx, C_bool(true));
2423-
2424-
// see the and case for an explanation
2425-
let rhs_bcx = trans_block_cleanups(rhs_res.bcx, rhs_cx);
2426-
CondBr(lhs_res.bcx, lhs_res.val, lhs_true_cx.llbb, rhs_cx.llbb);
2427-
ret join_results(cx, T_bool(),
2428-
[lhs_true_res, {bcx: rhs_bcx, val: rhs_res.val}]);
2425+
ast::and. | ast::or. {
2426+
ret trans_lazy_binop(cx, op, a, b, dest);
24292427
}
24302428
_ {
24312429
// Remaining cases are eager:
24322430
let lhs = trans_expr(cx, a);
24332431
let rhs = trans_expr(lhs.bcx, b);
2434-
24352432
ret trans_eager_binop(rhs.bcx, op, lhs.val,
24362433
ty::expr_ty(bcx_tcx(cx), a), rhs.val,
2437-
ty::expr_ty(bcx_tcx(cx), b));
2434+
ty::expr_ty(bcx_tcx(cx), b), dest);
24382435
}
24392436
}
24402437
}
24412438

2442-
fn join_results(parent_cx: @block_ctxt, t: TypeRef, ins: [result]) -> result {
2443-
let live: [result] = [];
2444-
let vals: [ValueRef] = [];
2445-
let bbs: [BasicBlockRef] = [];
2446-
for r: result in ins {
2447-
if !r.bcx.unreachable {
2448-
live += [r];
2449-
vals += [r.val];
2450-
bbs += [r.bcx.llbb];
2451-
}
2452-
}
2453-
alt std::vec::len::<result>(live) {
2454-
0u {
2455-
// No incoming edges are live, so we're in dead-code-land.
2456-
// Arbitrarily pick the first dead edge, since the caller
2457-
// is just going to propagate it outward.
2458-
assert (std::vec::len::<result>(ins) >= 1u);
2459-
ret ins[0];
2460-
}
2461-
_ {/* fall through */ }
2462-
}
2463-
// We have >1 incoming edges. Make a join block and br+phi them into it.
2464-
2465-
let join_cx = new_sub_block_ctxt(parent_cx, "join");
2466-
for r: result in live { Br(r.bcx, join_cx.llbb); }
2467-
let phi = Phi(join_cx, t, vals, bbs);
2468-
ret rslt(join_cx, phi);
2469-
}
2470-
24712439
// FIXME remove once all uses have been converted to join_returns
24722440
fn join_branches(parent_cx: @block_ctxt, ins: [result]) -> @block_ctxt {
24732441
let out = new_sub_block_ctxt(parent_cx, "join");
@@ -2483,6 +2451,7 @@ tag dest {
24832451
by_val(@mutable ValueRef);
24842452
by_ref(@mutable ValueRef);
24852453
save_in(ValueRef);
2454+
overwrite(ValueRef, ty::t);
24862455
ignore;
24872456
}
24882457

@@ -2529,6 +2498,20 @@ fn join_returns(parent_cx: @block_ctxt, in_cxs: [@block_ctxt],
25292498
ret out;
25302499
}
25312500

2501+
// Used to put an immediate value in a dest
2502+
fn store_in_dest(bcx: @block_ctxt, val: ValueRef, dest: dest) -> @block_ctxt {
2503+
alt dest {
2504+
ignore. {}
2505+
by_val(cell) { *cell = val; }
2506+
save_in(addr) { Store(bcx, val, addr); }
2507+
overwrite(addr, tp) {
2508+
bcx = drop_ty(bcx, addr, tp);
2509+
Store(bcx, val, addr);
2510+
}
2511+
}
2512+
ret bcx;
2513+
}
2514+
25322515
// Wrapper through which legacy non-DPS code can use DPS functions
25332516
fn dps_to_result(bcx: @block_ctxt,
25342517
work: block(@block_ctxt, dest) -> @block_ctxt,
@@ -4135,7 +4118,6 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
41354118
fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
41364119
// Fixme Fill in cx.sp
41374120
alt e.node {
4138-
ast::expr_binary(op, x, y) { ret trans_binary(cx, op, x, y); }
41394121
ast::expr_fn(f) {
41404122
let ccx = bcx_ccx(cx);
41414123
let fty = node_id_type(ccx, e.id);
@@ -4267,6 +4249,7 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
42674249
ast::expr_tup(args) { ret trans_tup(bcx, args, e.id, dest); }
42684250
ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); }
42694251
ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); }
4252+
ast::expr_binary(op, x, y) { ret trans_binary(bcx, op, x, y, dest); }
42704253

42714254
ast::expr_break. {
42724255
assert dest == ignore;
@@ -4399,6 +4382,9 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
43994382
*cell = val;
44004383
}
44014384
save_in(loc) { bcx = move_val_if_temp(bcx, INIT, loc, lv, ty); }
4385+
overwrite(loc, _) {
4386+
bcx = move_val_if_temp(bcx, DROP_EXISTING, loc, lv, ty);
4387+
}
44024388
ignore. {}
44034389
}
44044390
ret bcx;

trunk/src/comp/middle/trans_alt.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> result {
3636
lit(l) {
3737
alt l.node {
3838
ast::lit_str(s) {
39-
let {bcx, val: dst} =
40-
trans::alloc_ty(bcx, ty::mk_str(bcx_tcx(bcx)));
39+
let strty = ty::mk_str(bcx_tcx(bcx));
40+
let {bcx, val: dst} = trans::alloc_ty(bcx, strty);
4141
bcx = trans_vec::trans_str(bcx, s, trans::save_in(dst));
42+
add_clean_temp(bcx, dst, strty);
4243
ret rslt(bcx, dst);
4344
}
4445
_ {

trunk/src/comp/middle/trans_vec.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,14 @@ fn make_drop_glue(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t) ->
100100
ret next_cx;
101101
}
102102

103-
// FIXME handle dest == ignore
104103
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
105104
dest: dest) -> @block_ctxt {
105+
if dest == trans::ignore {
106+
for arg in args {
107+
bcx = trans::trans_expr_dps(bcx, arg, trans::ignore);
108+
}
109+
ret bcx;
110+
}
106111
let vec_ty = node_id_type(bcx_ccx(bcx), id);
107112
let {bcx: bcx,
108113
val: vptrptr,
@@ -113,17 +118,20 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
113118

114119
// Store the individual elements.
115120
let dataptr = get_dataptr(bcx, vptrptr, llunitty);
116-
let i = 0u;
121+
add_clean_temp_mem(bcx, vptrptr, vec_ty);
122+
let i = 0u, temp_cleanups = [vptrptr];
117123
for e in args {
118124
let lv = trans_lval(bcx, e);
119125
bcx = lv.bcx;
120-
let lleltptr =
121-
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
122-
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
123-
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
126+
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
127+
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
128+
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
124129
bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty);
130+
add_clean_temp_mem(bcx, lleltptr, unit_ty);
131+
temp_cleanups += [lleltptr];
125132
i += 1u;
126133
}
134+
for clean in temp_cleanups { revoke_clean(bcx, clean); }
127135
ret bcx;
128136
}
129137
fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
@@ -213,12 +221,11 @@ fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
213221
}
214222

215223
fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
216-
rhsptr: ValueRef) -> result {
217-
let strings =
218-
alt ty::struct(bcx_tcx(bcx), vec_ty) {
219-
ty::ty_str. { true }
220-
ty::ty_vec(_) { false }
221-
};
224+
rhsptr: ValueRef, dest: dest) -> @block_ctxt {
225+
let strings = alt ty::struct(bcx_tcx(bcx), vec_ty) {
226+
ty::ty_str. { true }
227+
ty::ty_vec(_) { false }
228+
};
222229
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
223230
let llunitty = type_of_or_i8(bcx, unit_ty);
224231
let {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty);
@@ -229,9 +236,8 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
229236
let new_fill = Add(bcx, lhs_fill, rhs_fill);
230237
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);
231238
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(llunitty)));
232-
let {bcx: bcx, val: new_vec_ptr_ptr} = alloc_ty(bcx, vec_ty);
239+
let new_vec_ptr_ptr = alt dest { trans::save_in(a) { a } };
233240
Store(bcx, new_vec_ptr, new_vec_ptr_ptr);
234-
add_clean_temp(bcx, new_vec_ptr_ptr, vec_ty);
235241

236242
let write_ptr_ptr =
237243
do_spill_noroot(bcx, get_dataptr(bcx, new_vec_ptr_ptr, llunitty));
@@ -252,8 +258,7 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
252258
}(_, _, _, write_ptr_ptr, unit_ty, llunitsz);
253259

254260
let bcx = iter_vec_raw(bcx, lhsptr, vec_ty, lhs_fill, copy_fn);
255-
let bcx = iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
256-
ret rslt(bcx, new_vec_ptr_ptr);
261+
ret iter_vec_raw(bcx, rhsptr, vec_ty, rhs_fill, copy_fn);
257262
}
258263

259264
type val_and_ty_fn = fn(@block_ctxt, ValueRef, ty::t) -> result;

0 commit comments

Comments
 (0)