Skip to content

Commit 652da4c

Browse files
committed
rustc: Implement immediates in the DPS engine; it should now always be at least as efficient as the original engine (and typically much more).
1 parent 88574c3 commit 652da4c

File tree

1 file changed

+49
-16
lines changed

1 file changed

+49
-16
lines changed

src/comp/middle/trans_dps.rs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,16 @@ fn llelement_type(TypeRef llty) -> TypeRef {
4141

4242
tag dest_slot {
4343
dst_nil;
44-
dst_val(ValueRef);
44+
dst_imm(@mutable option[ValueRef]);
45+
dst_ptr(ValueRef);
4546
}
4647

4748
tag dest_mode { dm_copy; dm_move; dm_alias; }
4849

4950
type dest = rec(dest_slot slot, dest_mode mode);
5051

5152
fn dest_slot_for_ptr(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest_slot {
52-
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_val(llptr) }
53+
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_ptr(llptr) }
5354
}
5455

5556
fn dest_copy(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
@@ -69,16 +70,34 @@ fn dest_tmp(&@block_ctxt bcx, ty::t t, bool alias) -> tup(@block_ctxt, dest) {
6970
if ty::type_is_nil(bcx_tcx(bcx), t) {
7071
ret tup(bcx, rec(slot=dst_nil, mode=mode));
7172
}
73+
if trans::type_is_immediate(bcx_ccx(bcx), t) {
74+
ret tup(bcx, rec(slot=dst_imm(@mutable none), mode=mode));
75+
}
7276
auto r = trans::alloc_ty(bcx, t);
7377
trans::add_clean(bcx, r.val, t);
7478
ret tup(r.bcx, rec(slot=dest_slot_for_ptr(bcx_tcx(bcx), r.val, t),
7579
mode=mode));
7680
}
7781

82+
// Invariant: the type of the destination must be structural (non-immediate).
7883
fn dest_ptr(&dest dest) -> ValueRef {
7984
alt (dest.slot) {
80-
dst_nil { tc::C_null(tc::T_ptr(tc::T_i8())) }
81-
dst_val(?llptr) { llptr }
85+
dst_nil { fail "nil dest in dest_ptr" }
86+
dst_imm(_) { fail "immediate dest in dest_ptr" }
87+
dst_ptr(?llptr) { llptr }
88+
}
89+
}
90+
91+
fn dest_llval(&dest dest) -> ValueRef {
92+
alt (dest.slot) {
93+
dst_nil { ret tc::C_nil(); }
94+
dst_imm(?box) {
95+
alt (*box) {
96+
none { fail "immediate wasn't filled in prior to dest_llval"; }
97+
some(?llval) { ret llval; }
98+
}
99+
}
100+
dst_ptr(?llval) { ret llval; }
82101
}
83102
}
84103

@@ -100,9 +119,15 @@ fn store(&@block_ctxt bcx, &dest dest, ValueRef llsrc, bool cast)
100119
-> @block_ctxt {
101120
alt (dest.slot) {
102121
dst_nil { /* no-op */ }
103-
dst_val(?lldestptr_orig) {
122+
dst_imm(?box) {
123+
if !std::option::is_none(*box) {
124+
fail "attempt to store an immediate twice";
125+
};
126+
*box = some(llsrc);
127+
}
128+
dst_ptr(?lldestptr_orig) {
104129
auto lldestptr = lldestptr_orig;
105-
if (cast) {
130+
if cast {
106131
lldestptr = bcx.build.PointerCast(lldestptr,
107132
tc::T_ptr(lltype_of(llsrc)));
108133
}
@@ -201,39 +226,47 @@ fn trans_log(&@block_ctxt cx, &span sp, int level, &@ast::expr expr)
201226
ret lllevelptr;
202227
}
203228

204-
fn trans_log_upcall(&@block_ctxt bcx, &span sp, ValueRef in_llval,
205-
int level, ty::t t) {
229+
fn trans_log_upcall(&@block_ctxt cx, &span sp, ValueRef in_llval,
230+
int level, ty::t t) -> @block_ctxt {
231+
auto bcx = cx;
206232
auto llval = in_llval;
207-
auto by_val; auto llupcall;
233+
auto llupcall;
208234
alt (ty::struct(bcx_tcx(bcx), t)) {
209235
ty::ty_machine(ast::ty_f32) {
210-
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_float;
236+
llupcall = bcx_ccx(bcx).upcalls.log_float;
211237
}
212238
ty::ty_machine(ast::ty_f64) | ty::ty_float {
213-
by_val = false; llupcall = bcx_ccx(bcx).upcalls.log_double;
239+
llupcall = bcx_ccx(bcx).upcalls.log_double;
240+
241+
// TODO: Here we have to spill due to legacy calling conventions.
242+
// This is no longer necessary.
243+
auto r = trans::alloc_ty(bcx, t);
244+
bcx = r.bcx; auto llptr = r.val;
245+
bcx.build.Store(llval, llptr);
246+
llval = llptr;
214247
}
215248
ty::ty_bool | ty::ty_machine(ast::ty_i8) |
216249
ty::ty_machine(ast::ty_i16) | ty::ty_machine(ast::ty_u8) |
217250
ty::ty_machine(ast::ty_u16) {
218-
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_int;
251+
llupcall = bcx_ccx(bcx).upcalls.log_int;
219252
llval = bcx.build.ZExt(llval, tc::T_i32());
220253
}
221254
ty::ty_int | ty::ty_machine(ast::ty_i32) |
222255
ty::ty_machine(ast::ty_u32) {
223-
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_int;
256+
llupcall = bcx_ccx(bcx).upcalls.log_int;
224257
}
225258
ty::ty_istr {
226-
by_val = false; llupcall = bcx_ccx(bcx).upcalls.log_istr;
259+
llupcall = bcx_ccx(bcx).upcalls.log_istr;
227260
}
228261
_ {
229262
bcx_ccx(bcx).sess.span_unimpl(sp, "logging for values of type " +
230263
ppaux::ty_to_str(bcx_tcx(bcx), t));
231264
}
232265
}
233266

234-
if by_val { llval = bcx.build.Load(llval); }
235267
bcx.build.Call(llupcall,
236268
~[bcx_fcx(bcx).lltaskptr, tc::C_int(level), llval]);
269+
ret bcx;
237270
}
238271

239272
auto bcx = cx;
@@ -253,7 +286,7 @@ fn trans_log(&@block_ctxt cx, &span sp, int level, &@ast::expr expr)
253286
log_bcx = r._0; auto tmp = r._1;
254287
log_bcx = trans_expr(log_bcx, tmp, expr);
255288

256-
trans_log_upcall(log_bcx, sp, dest_ptr(tmp), level, expr_t);
289+
log_bcx = trans_log_upcall(log_bcx, sp, dest_llval(tmp), level, expr_t);
257290

258291
log_bcx = trans::trans_block_cleanups(log_bcx,
259292
trans::find_scope_cx(log_bcx));

0 commit comments

Comments
 (0)