Skip to content

Commit a6e94f9

Browse files
committed
---
yaml --- r: 3975 b: refs/heads/master c: 437b776 h: refs/heads/master i: 3973: 741414c 3971: 1afa2db 3967: a59c27b v: v3
1 parent a9e4c98 commit a6e94f9

File tree

2 files changed

+104
-91
lines changed

2 files changed

+104
-91
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 09ca57adb0290b015ea54dd44f20c781b98297b9
2+
refs/heads/master: 437b77610001d7fc9b41ce50d82db94cc3c642ac

trunk/src/comp/middle/trans_dps.rs

+103-90
Original file line numberDiff line numberDiff line change
@@ -64,68 +64,65 @@ fn mk_const(&@crate_ctxt ccx, &str name, bool exported, ValueRef llval)
6464

6565
// Destination utilities
6666

67-
tag dest_slot {
68-
dst_nil;
69-
dst_imm(@mutable option[ValueRef]);
70-
dst_ptr(ValueRef);
67+
tag dest {
68+
dst_nil; // Unit destination; ignore.
69+
dst_imm(@mutable option[ValueRef]); // Fill with an immediate value.
70+
dst_alias(@mutable option[ValueRef]); // Fill with an alias pointer.
71+
dst_copy(ValueRef); // Copy to the given address.
72+
dst_move(ValueRef); // Move to the given address.
7173
}
7274

73-
tag dest_mode { dm_copy; dm_move; dm_alias; }
74-
75-
type dest = rec(dest_slot slot, dest_mode mode);
75+
fn dest_imm(&ty::ctxt tcx, ty::t t) -> dest {
76+
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_imm(@mutable none) }
77+
}
7678

77-
fn dest_slot_for_ptr(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest_slot {
78-
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_ptr(llptr) }
79+
fn dest_alias(&ty::ctxt tcx, ty::t t) -> dest {
80+
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_alias(@mutable none) }
7981
}
8082

8183
fn dest_copy(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
82-
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_copy);
84+
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_copy(llptr) }
8385
}
8486

8587
fn dest_move(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
86-
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_move);
87-
}
88-
89-
fn dest_alias(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
90-
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_alias);
91-
}
92-
93-
fn dest_tmp(&@block_ctxt bcx, ty::t t, bool alias) -> tup(@block_ctxt, dest) {
94-
auto mode = if alias { dm_alias } else { dm_move };
95-
if ty::type_is_nil(bcx_tcx(bcx), t) {
96-
ret tup(bcx, rec(slot=dst_nil, mode=mode));
97-
}
98-
if trans::type_is_immediate(bcx_ccx(bcx), t) {
99-
ret tup(bcx, rec(slot=dst_imm(@mutable none), mode=mode));
100-
}
101-
auto r = trans::alloc_ty(bcx, t);
102-
trans::add_clean(bcx, r.val, t);
103-
ret tup(r.bcx, rec(slot=dest_slot_for_ptr(bcx_tcx(bcx), r.val, t),
104-
mode=mode));
88+
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_move(llptr) }
10589
}
10690

10791
// Invariant: the type of the destination must be structural (non-immediate).
10892
fn dest_ptr(&dest dest) -> ValueRef {
109-
alt (dest.slot) {
93+
alt (dest) {
11094
dst_nil { fail "nil dest in dest_ptr" }
11195
dst_imm(_) { fail "immediate dest in dest_ptr" }
112-
dst_ptr(?llptr) { llptr }
96+
dst_alias(_) { fail "alias dest in dest_ptr" }
97+
dst_copy(?llptr) { llptr }
98+
dst_move(?llptr) { llptr }
11399
}
114100
}
115101

116102
fn dest_llval(&dest dest) -> ValueRef {
117-
alt (dest.slot) {
103+
alt (dest) {
118104
dst_nil { ret tc::C_nil(); }
119105
dst_imm(?box) {
120106
alt (*box) {
121107
none { fail "immediate wasn't filled in prior to dest_llval"; }
122108
some(?llval) { ret llval; }
123109
}
124110
}
125-
dst_ptr(?llval) { ret llval; }
111+
dst_alias(?box) {
112+
alt (*box) {
113+
none { fail "alias wasn't filled in prior to dest_llval"; }
114+
some(?llval) { ret llval; }
115+
}
116+
}
117+
dst_copy(?llptr) { ret llptr; }
118+
dst_move(?llptr) { ret llptr; }
126119
}
127120
}
128121

122+
fn dest_is_alias(&dest dest) -> bool {
123+
alt (dest) { dst_alias(_) { true } _ { false } }
124+
}
125+
129126

130127
// Accessors
131128
// TODO: When we have overloading, simplify these names!
@@ -135,42 +132,44 @@ fn bcx_ccx(&@block_ctxt bcx) -> @crate_ctxt { ret bcx.fcx.lcx.ccx; }
135132
fn bcx_lcx(&@block_ctxt bcx) -> @local_ctxt { ret bcx.fcx.lcx; }
136133
fn bcx_fcx(&@block_ctxt bcx) -> @fn_ctxt { ret bcx.fcx; }
137134
fn lcx_ccx(&@local_ctxt lcx) -> @crate_ctxt { ret lcx.ccx; }
135+
fn ccx_tcx(&@crate_ctxt ccx) -> ty::ctxt { ret ccx.tcx; }
138136

139137

140138
// Common operations
141139

142140
// If "cast" is true, casts dest appropriately before the store.
143-
fn store(&@block_ctxt bcx, &dest dest, ValueRef llsrc, bool cast)
141+
fn store_imm(&@block_ctxt bcx, &dest dest, ValueRef llsrc, bool cast)
144142
-> @block_ctxt {
145-
alt (dest.slot) {
143+
alt (dest) {
146144
dst_nil { /* no-op */ }
147145
dst_imm(?box) {
148-
if !std::option::is_none(*box) {
149-
fail "attempt to store an immediate twice";
150-
};
146+
assert (std::option::is_none(*box));
151147
*box = some(llsrc);
152148
}
153-
dst_ptr(?lldestptr_orig) {
149+
dst_alias(?box) {
150+
bcx_ccx(bcx).sess.unimpl("dst_alias spill in store_imm");
151+
}
152+
dst_copy(?lldestptr_orig) | dst_move(?lldestptr_orig) {
154153
auto lldestptr = lldestptr_orig;
155154
if cast {
156155
lldestptr = bcx.build.PointerCast(lldestptr,
157156
tc::T_ptr(lltype_of(llsrc)));
158157
}
159-
160158
bcx.build.Store(llsrc, lldestptr);
161159
}
162160
}
163161
ret bcx;
164162
}
165163

166-
fn memmove(&@block_ctxt bcx, &dest dest, ValueRef llsrcptr) -> @block_ctxt {
167-
alt (dest.slot) {
168-
// TODO: We might want to support these; I can't think of any case in
169-
// which we would want them off the top of my head, but feel free to add
170-
// them if they aid orthogonality.
171-
dst_nil { fail "dst_nil in memmove"; }
172-
dst_imm(_) { fail "dst_imm in memmove"; }
173-
dst_ptr(?lldestptr) {
164+
fn store_ptr(&@block_ctxt bcx, &dest dest, ValueRef llsrcptr) -> @block_ctxt {
165+
alt (dest) {
166+
dst_nil { /* no-op */ }
167+
dst_imm(?box) { fail "dst_imm in store_ptr"; }
168+
dst_alias(?box) {
169+
assert (std::option::is_none(*box));
170+
*box = some(llsrcptr);
171+
}
172+
dst_copy(?lldestptr) | dst_move(?lldestptr) {
174173
auto lldestty = llelement_type(trans::val_ty(llsrcptr));
175174
auto llsrcty = llelement_type(trans::val_ty(llsrcptr));
176175
auto dest_align = llalign_of(bcx_ccx(bcx), lldestty);
@@ -190,6 +189,7 @@ fn memmove(&@block_ctxt bcx, &dest dest, ValueRef llsrcptr) -> @block_ctxt {
190189
ret bcx;
191190
}
192191
}
192+
ret bcx;
193193
}
194194

195195
// Allocates a value of the given LLVM size on either the task heap or the
@@ -228,9 +228,9 @@ fn trans_lit(&@block_ctxt cx, &dest dest, &ast::lit lit) -> @block_ctxt {
228228
auto bcx = cx;
229229
alt (lit.node) {
230230
ast::lit_str(?s, ast::sk_unique) {
231-
auto r = trans_lit_str_common(bcx_ccx(bcx), s);
231+
auto r = trans_lit_str_common(bcx_ccx(bcx), s, dest_is_alias(dest));
232232
auto llstackpart = r._0; auto llheappartopt = r._1;
233-
bcx = memmove(bcx, dest, llstackpart);
233+
bcx = store_ptr(bcx, dest, llstackpart);
234234
alt (llheappartopt) {
235235
none { /* no-op */ }
236236
some(?llheappart) {
@@ -244,13 +244,13 @@ fn trans_lit(&@block_ctxt cx, &dest dest, &ast::lit lit) -> @block_ctxt {
244244
tc::T_ptr(tc::T_ptr(llheappartty)));
245245
malloc(bcx, lldestptrptr, hp_shared, none);
246246
auto lldestptr = bcx.build.Load(lldestptrptr);
247-
memmove(bcx, rec(slot=dst_ptr(lldestptr), mode=dm_copy),
248-
llheappart);
247+
store_ptr(bcx, dst_copy(lldestptr), llheappart);
249248
}
250249
}
251250
}
252251
_ {
253-
bcx = store(bcx, dest, trans_lit_common(bcx_ccx(bcx), lit), false);
252+
bcx = store_imm(bcx, dest, trans_lit_common(bcx_ccx(bcx), lit),
253+
false);
254254
}
255255
}
256256

@@ -280,47 +280,35 @@ fn trans_log(&@block_ctxt cx, &span sp, int level, &@ast::expr expr)
280280
ret lllevelptr;
281281
}
282282

283-
fn trans_log_upcall(&@block_ctxt cx, &span sp, ValueRef in_llval,
284-
int level, ty::t t) -> @block_ctxt {
285-
auto bcx = cx;
286-
auto llval = in_llval;
287-
auto llupcall;
288-
alt (ty::struct(bcx_tcx(bcx), t)) {
283+
tag upcall_style { us_imm; us_imm_i32_zext; us_alias; us_alias_istr; }
284+
fn get_upcall(&@crate_ctxt ccx, &span sp, ty::t t)
285+
-> tup(ValueRef, upcall_style) {
286+
alt (ty::struct(ccx_tcx(ccx), t)) {
289287
ty::ty_machine(ast::ty_f32) {
290-
llupcall = bcx_ccx(bcx).upcalls.log_float;
288+
ret tup(ccx.upcalls.log_float, us_imm);
291289
}
292290
ty::ty_machine(ast::ty_f64) | ty::ty_float {
293-
llupcall = bcx_ccx(bcx).upcalls.log_double;
294-
295-
// TODO: Here we have to spill due to legacy calling conventions.
296-
// This is no longer necessary.
297-
auto r = trans::alloc_ty(bcx, t);
298-
bcx = r.bcx; auto llptr = r.val;
299-
bcx.build.Store(llval, llptr);
300-
llval = llptr;
291+
// TODO: We have to spill due to legacy calling conventions that
292+
// should probably be modernized.
293+
ret tup(ccx.upcalls.log_double, us_alias);
301294
}
302295
ty::ty_bool | ty::ty_machine(ast::ty_i8) |
303296
ty::ty_machine(ast::ty_i16) | ty::ty_machine(ast::ty_u8) |
304297
ty::ty_machine(ast::ty_u16) {
305-
llupcall = bcx_ccx(bcx).upcalls.log_int;
306-
llval = bcx.build.ZExt(llval, tc::T_i32());
298+
ret tup(ccx.upcalls.log_int, us_imm_i32_zext);
307299
}
308300
ty::ty_int | ty::ty_machine(ast::ty_i32) |
309301
ty::ty_machine(ast::ty_u32) {
310-
llupcall = bcx_ccx(bcx).upcalls.log_int;
302+
ret tup(ccx.upcalls.log_int, us_imm);
311303
}
312304
ty::ty_istr {
313-
llupcall = bcx_ccx(bcx).upcalls.log_istr;
305+
ret tup(ccx.upcalls.log_istr, us_alias_istr);
314306
}
315307
_ {
316-
bcx_ccx(bcx).sess.span_unimpl(sp, "logging for values of type " +
317-
ppaux::ty_to_str(bcx_tcx(bcx), t));
308+
ccx.sess.span_unimpl(sp, "logging for values of type " +
309+
ppaux::ty_to_str(ccx_tcx(ccx), t));
318310
}
319311
}
320-
321-
bcx.build.Call(llupcall,
322-
~[bcx_fcx(bcx).lltaskptr, tc::C_int(level), llval]);
323-
ret bcx;
324312
}
325313

326314
auto bcx = cx;
@@ -336,11 +324,32 @@ fn trans_log(&@block_ctxt cx, &span sp, int level, &@ast::expr expr)
336324
bcx.build.CondBr(should_log, log_bcx.llbb, next_bcx.llbb);
337325

338326
auto expr_t = ty::expr_ty(bcx_tcx(log_bcx), expr);
339-
auto r = dest_tmp(log_bcx, expr_t, true);
340-
log_bcx = r._0; auto tmp = r._1;
341-
log_bcx = trans_expr(log_bcx, tmp, expr);
327+
auto r = get_upcall(bcx_ccx(bcx), sp, expr_t);
328+
auto llupcall = r._0; auto style = r._1;
342329

343-
log_bcx = trans_log_upcall(log_bcx, sp, dest_llval(tmp), level, expr_t);
330+
auto arg_dest;
331+
alt (style) {
332+
us_imm | us_imm_i32_zext {
333+
arg_dest = dest_imm(bcx_tcx(log_bcx), expr_t);
334+
}
335+
us_alias | us_alias_istr {
336+
arg_dest = dest_alias(bcx_tcx(log_bcx), expr_t);
337+
}
338+
}
339+
log_bcx = trans_expr(log_bcx, arg_dest, expr);
340+
341+
auto llarg = dest_llval(arg_dest);
342+
alt (style) {
343+
us_imm | us_alias { /* no-op */ }
344+
us_imm_i32_zext { llarg = log_bcx.build.ZExt(llarg, tc::T_i32()); }
345+
us_alias_istr {
346+
llarg = log_bcx.build.PointerCast(llarg,
347+
tc::T_ptr(tc::T_ivec(tc::T_i8())));
348+
}
349+
}
350+
351+
log_bcx.build.Call(llupcall,
352+
~[bcx_fcx(bcx).lltaskptr, tc::C_int(level), llarg]);
344353

345354
log_bcx = trans::trans_block_cleanups(log_bcx,
346355
trans::find_scope_cx(log_bcx));
@@ -393,7 +402,10 @@ fn trans_block(&@block_ctxt cx, &dest dest, &ast::block block)
393402
// Common setup code shared between the crate-constant literal string case and
394403
// the block-local literal string case. We don't use destination-passing style
395404
// since that doesn't work for crate constants.
396-
fn trans_lit_str_common(&@crate_ctxt ccx, &str s)
405+
//
406+
// If |expand| is true, we never spill to the heap. This should be used
407+
// whenever the destination size isn't fixed.
408+
fn trans_lit_str_common(&@crate_ctxt ccx, &str s, bool expand)
397409
-> tup(ValueRef, option[ValueRef]) {
398410
auto llstackpart; auto llheappartopt;
399411

@@ -403,7 +415,12 @@ fn trans_lit_str_common(&@crate_ctxt ccx, &str s)
403415
for (u8 ch in s) { array += ~[tc::C_u8(ch as uint)]; }
404416
array += ~[tc::C_u8(0u)];
405417

406-
if len < abi::ivec_default_length - 1u { // minus 1 because of the \0
418+
if expand {
419+
llstackpart = tc::C_struct(~[tc::C_uint(len + 1u),
420+
tc::C_uint(len + 1u),
421+
tc::C_array(tc::T_i8(), array)]);
422+
llheappartopt = none;
423+
} else if len < abi::ivec_default_length - 1u { // minus one for the null
407424
while (ivec::len(array) < abi::ivec_default_length) {
408425
array += ~[tc::C_u8(0u)];
409426
}
@@ -492,19 +509,15 @@ fn trans_init_local(&@block_ctxt bcx, &@ast::local local) -> @block_ctxt {
492509
}
493510
}
494511
}
495-
none {
496-
ret store(bcx, dest_copy(bcx_tcx(bcx), llptr, t),
497-
tc::C_null(llelement_type(trans::val_ty(llptr))), false);
498-
}
512+
none { ret bcx; }
499513
}
500514
}
501515

502516
fn trans_stmt(&@block_ctxt cx, &@ast::stmt stmt) -> @block_ctxt {
503517
auto bcx = cx;
504518
alt (stmt.node) {
505519
ast::stmt_expr(?e, _) {
506-
auto tmp_r = dest_tmp(bcx, ty::expr_ty(bcx_tcx(bcx), e), true);
507-
bcx = tmp_r._0; auto tmp = tmp_r._1;
520+
auto tmp = dest_alias(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e));
508521
ret trans_expr(bcx, tmp, e);
509522
}
510523
ast::stmt_decl(?d, _) {

0 commit comments

Comments
 (0)