Skip to content

Commit fae8599

Browse files
committed
---
yaml --- r: 3954 b: refs/heads/master c: f6f7f61 h: refs/heads/master v: v3
1 parent cf56c4b commit fae8599

File tree

2 files changed

+110
-10
lines changed

2 files changed

+110
-10
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: 69abf0a5ffc20854f18a1fd720906c4f94cae7f7
2+
refs/heads/master: f6f7f6190809d698f39f5f3dde9a10cb28661795

trunk/src/comp/middle/trans_dps.rs

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
// destination-passing style.
33

44
import back::abi;
5+
import back::link;
56
import lib::llvm::llvm;
67
import llvm::TypeRef;
78
import llvm::ValueRef;
89
import middle::trans;
910
import middle::ty;
1011
import syntax::ast;
12+
import syntax::codemap::span;
1113
import trans::block_ctxt;
1214
import trans::crate_ctxt;
1315
import trans::fn_ctxt;
1416
import trans::local_ctxt;
17+
import util::ppaux;
1518

1619
import std::ivec;
1720
import std::option::none;
@@ -20,6 +23,7 @@ import std::str;
2023

2124
import LLFalse = lib::llvm::False;
2225
import LLTrue = lib::llvm::True;
26+
import ll = lib::llvm;
2327
import lltype_of = trans::val_ty;
2428
import option = std::option::t;
2529
import tc = trans_common;
@@ -40,26 +44,35 @@ tag dest_slot {
4044
dst_val(ValueRef);
4145
}
4246

43-
type dest = rec(dest_slot slot, bool move);
47+
tag dest_mode { dm_copy; dm_move; dm_alias; }
48+
49+
type dest = rec(dest_slot slot, dest_mode mode);
4450

4551
fn dest_slot_for_ptr(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest_slot {
4652
if ty::type_is_nil(tcx, t) { dst_nil } else { dst_val(llptr) }
4753
}
4854

4955
fn dest_copy(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
50-
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), move=false);
56+
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_copy);
5157
}
5258

5359
fn dest_move(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
54-
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), move=true);
60+
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_move);
61+
}
62+
63+
fn dest_alias(&ty::ctxt tcx, ValueRef llptr, ty::t t) -> dest {
64+
ret rec(slot=dest_slot_for_ptr(tcx, llptr, t), mode=dm_alias);
5565
}
5666

57-
fn dest_tmp(&@block_ctxt bcx, ty::t t) -> tup(@block_ctxt, dest) {
67+
fn dest_tmp(&@block_ctxt bcx, ty::t t, bool alias) -> tup(@block_ctxt, dest) {
68+
auto mode = if alias { dm_alias } else { dm_move };
5869
if ty::type_is_nil(bcx_tcx(bcx), t) {
59-
ret tup(bcx, rec(slot=dst_nil, move=true));
70+
ret tup(bcx, rec(slot=dst_nil, mode=mode));
6071
}
6172
auto r = trans::alloc_ty(bcx, t);
62-
ret tup(r.bcx, dest_move(bcx_tcx(bcx), r.val, t));
73+
trans::add_clean(bcx, r.val, t);
74+
ret tup(r.bcx, rec(slot=dest_slot_for_ptr(bcx_tcx(bcx), r.val, t),
75+
mode=mode));
6376
}
6477

6578
fn dest_ptr(&dest dest) -> ValueRef {
@@ -77,6 +90,7 @@ fn bcx_tcx(&@block_ctxt bcx) -> ty::ctxt { ret bcx.fcx.lcx.ccx.tcx; }
7790
fn bcx_ccx(&@block_ctxt bcx) -> @crate_ctxt { ret bcx.fcx.lcx.ccx; }
7891
fn bcx_lcx(&@block_ctxt bcx) -> @local_ctxt { ret bcx.fcx.lcx; }
7992
fn bcx_fcx(&@block_ctxt bcx) -> @fn_ctxt { ret bcx.fcx; }
93+
fn lcx_ccx(&@local_ctxt lcx) -> @crate_ctxt { ret lcx.ccx; }
8094

8195

8296
// Common operations
@@ -164,9 +178,92 @@ fn trans_lit(&@block_ctxt cx, &dest dest, &ast::lit lit) -> @block_ctxt {
164178
ret bcx;
165179
}
166180

181+
fn trans_log(&@block_ctxt cx, &span sp, int level, &@ast::expr expr)
182+
-> @block_ctxt {
183+
fn trans_log_level(&@local_ctxt lcx) -> ValueRef {
184+
auto modname = str::connect_ivec(lcx.module_path, "::");
185+
186+
if (lcx_ccx(lcx).module_data.contains_key(modname)) {
187+
ret lcx_ccx(lcx).module_data.get(modname);
188+
}
189+
190+
auto s =
191+
link::mangle_internal_name_by_path_and_seq(lcx_ccx(lcx),
192+
lcx.module_path,
193+
"loglevel");
194+
auto lllevelptr = llvm::LLVMAddGlobal(lcx.ccx.llmod, tc::T_int(),
195+
str::buf(s));
196+
llvm::LLVMSetGlobalConstant(lllevelptr, LLFalse);
197+
llvm::LLVMSetInitializer(lllevelptr, tc::C_int(0));
198+
llvm::LLVMSetLinkage(lllevelptr, lib::llvm::LLVMInternalLinkage as
199+
llvm::Linkage);
200+
lcx_ccx(lcx).module_data.insert(modname, lllevelptr);
201+
ret lllevelptr;
202+
}
203+
204+
fn trans_log_upcall(&@block_ctxt bcx, &span sp, ValueRef in_llval,
205+
int level, ty::t t) {
206+
auto llval = in_llval;
207+
auto by_val; auto llupcall;
208+
alt (ty::struct(bcx_tcx(bcx), t)) {
209+
ty::ty_machine(ast::ty_f32) {
210+
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_float;
211+
}
212+
ty::ty_machine(ast::ty_f64) | ty::ty_float {
213+
by_val = false; llupcall = bcx_ccx(bcx).upcalls.log_double;
214+
}
215+
ty::ty_bool | ty::ty_machine(ast::ty_i8) |
216+
ty::ty_machine(ast::ty_i16) | ty::ty_machine(ast::ty_u8) |
217+
ty::ty_machine(ast::ty_u16) {
218+
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_int;
219+
llval = bcx.build.ZExt(llval, tc::T_i32());
220+
}
221+
ty::ty_int | ty::ty_machine(ast::ty_i32) |
222+
ty::ty_machine(ast::ty_u32) {
223+
by_val = true; llupcall = bcx_ccx(bcx).upcalls.log_int;
224+
}
225+
_ {
226+
bcx_ccx(bcx).sess.span_unimpl(sp, "logging for values of type " +
227+
ppaux::ty_to_str(bcx_tcx(bcx), t));
228+
}
229+
}
230+
231+
if by_val { llval = bcx.build.Load(llval); }
232+
bcx.build.Call(llupcall,
233+
~[bcx_fcx(bcx).lltaskptr, tc::C_int(level), llval]);
234+
}
235+
236+
auto bcx = cx;
237+
238+
auto lllevelptr = trans_log_level(bcx_lcx(bcx));
239+
240+
auto log_bcx = trans::new_scope_block_ctxt(bcx, "log");
241+
auto next_bcx = trans::new_scope_block_ctxt(bcx, "next_log");
242+
243+
auto should_log = bcx.build.ICmp(ll::LLVMIntSGE,
244+
bcx.build.Load(lllevelptr),
245+
tc::C_int(level));
246+
bcx.build.CondBr(should_log, log_bcx.llbb, next_bcx.llbb);
247+
248+
auto expr_t = ty::expr_ty(bcx_tcx(log_bcx), expr);
249+
auto r = dest_tmp(log_bcx, expr_t, true);
250+
log_bcx = r._0; auto tmp = r._1;
251+
log_bcx = trans_expr(log_bcx, tmp, expr);
252+
253+
trans_log_upcall(log_bcx, sp, dest_ptr(tmp), level, expr_t);
254+
255+
log_bcx = trans::trans_block_cleanups(log_bcx,
256+
trans::find_scope_cx(log_bcx));
257+
log_bcx.build.Br(next_bcx.llbb);
258+
ret next_bcx;
259+
}
260+
167261
fn trans_expr(&@block_ctxt bcx, &dest dest, &@ast::expr expr) -> @block_ctxt {
168262
alt (expr.node) {
169263
ast::expr_lit(?lit) { trans_lit(bcx, dest, *lit); ret bcx; }
264+
ast::expr_log(?level, ?operand) {
265+
ret trans_log(bcx, expr.span, level, operand);
266+
}
170267
_ { fail "unhandled expr type in trans_expr"; }
171268
}
172269
}
@@ -191,9 +288,12 @@ fn trans_block(&@block_ctxt cx, &dest dest, &ast::block block)
191288
}
192289

193290
alt (block.node.expr) {
194-
some(?e) { ret trans_expr(bcx, dest, e); }
195-
none { ret bcx; }
291+
some(?e) { bcx = trans_expr(bcx, dest, e); }
292+
none { /* no-op */ }
196293
}
294+
295+
bcx = trans::trans_block_cleanups(bcx, trans::find_scope_cx(bcx));
296+
ret bcx;
197297
}
198298

199299

@@ -305,7 +405,7 @@ fn trans_stmt(&@block_ctxt cx, &@ast::stmt stmt) -> @block_ctxt {
305405
auto bcx = cx;
306406
alt (stmt.node) {
307407
ast::stmt_expr(?e, _) {
308-
auto tmp_r = dest_tmp(bcx, ty::expr_ty(bcx_tcx(bcx), e));
408+
auto tmp_r = dest_tmp(bcx, ty::expr_ty(bcx_tcx(bcx), e), true);
309409
bcx = tmp_r._0; auto tmp = tmp_r._1;
310410
ret trans_expr(bcx, tmp, e);
311411
}

0 commit comments

Comments
 (0)