Skip to content

Commit 5fefffb

Browse files
committed
---
yaml --- r: 3952 b: refs/heads/master c: 0bd7b80 h: refs/heads/master v: v3
1 parent b50983c commit 5fefffb

File tree

2 files changed

+175
-8
lines changed

2 files changed

+175
-8
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: 6e114a367f97c3388240746ca506b1e34416a71d
2+
refs/heads/master: 0bd7b803f697e9ee10f44c80a34a1abccf933555

trunk/src/comp/middle/trans_dps.rs

Lines changed: 174 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
// Translates individual functions in the completed AST to the LLVM IR, using
22
// destination-passing style.
33

4-
import syntax::ast;
4+
import back::abi;
5+
import lib::llvm::llvm;
6+
import llvm::TypeRef;
7+
import llvm::ValueRef;
58
import middle::trans;
69
import middle::ty;
10+
import syntax::ast;
711
import trans::block_ctxt;
812
import trans::crate_ctxt;
913
import trans::fn_ctxt;
1014
import trans::local_ctxt;
11-
import lib::llvm::llvm::TypeRef;
12-
import lib::llvm::llvm::ValueRef;
15+
16+
import std::ivec;
1317
import std::option::none;
1418
import std::option::some;
19+
import std::str;
1520

21+
import LLFalse = lib::llvm::False;
22+
import LLTrue = lib::llvm::True;
23+
import lltype_of = trans::val_ty;
24+
import option = std::option::t;
25+
import tc = trans_common;
1626
import type_of_node = trans::node_id_type;
1727

1828

@@ -52,6 +62,13 @@ fn dest_tmp(&@block_ctxt bcx, ty::t t) -> tup(@block_ctxt, dest) {
5262
ret tup(r.bcx, dest_move(bcx_tcx(bcx), r.val, t));
5363
}
5464

65+
fn dest_ptr(&dest dest) -> ValueRef {
66+
alt (dest.slot) {
67+
dst_nil { tc::C_null(tc::T_ptr(tc::T_i8())) }
68+
dst_val(?llptr) { llptr }
69+
}
70+
}
71+
5572

5673
// Accessors
5774
// TODO: When we have overloading, simplify these names!
@@ -64,19 +81,94 @@ fn bcx_fcx(&@block_ctxt bcx) -> @fn_ctxt { ret bcx.fcx; }
6481

6582
// Common operations
6683

67-
fn store(&@block_ctxt bcx, &dest dest, ValueRef llsrc) -> @block_ctxt {
84+
// If "cast" is true, casts dest appropriately before the store.
85+
fn store(&@block_ctxt bcx, &dest dest, ValueRef llsrc, bool cast)
86+
-> @block_ctxt {
6887
alt (dest.slot) {
6988
dst_nil { /* no-op */ }
70-
dst_val(?lldest) { bcx.build.Store(llsrc, lldest); }
89+
dst_val(?lldestptr_orig) {
90+
auto lldestptr = lldestptr_orig;
91+
if (cast) {
92+
lldestptr = bcx.build.PointerCast(lldestptr,
93+
tc::T_ptr(lltype_of(llsrc)));
94+
}
95+
96+
bcx.build.Store(llsrc, lldestptr);
97+
}
98+
}
99+
ret bcx;
100+
}
101+
102+
tag heap { hp_task; hp_shared; }
103+
104+
// Allocates a value of the given LLVM size on either the task heap or the
105+
// shared heap.
106+
fn malloc(&@block_ctxt bcx, ValueRef lldest, heap heap,
107+
option[ValueRef] llcustom_size_opt) -> @block_ctxt {
108+
auto llptrty = llelement_type(lltype_of(lldest));
109+
auto llty = llelement_type(llptrty);
110+
111+
auto lltydescptr = tc::C_null(tc::T_ptr(bcx_ccx(bcx).tydesc_type));
112+
113+
auto llsize;
114+
alt (llcustom_size_opt) {
115+
none { llsize = trans::llsize_of(llty); }
116+
some(?llcustom_size) { llsize = llcustom_size; }
117+
}
118+
119+
auto llupcall;
120+
alt (heap) {
121+
hp_task { llupcall = bcx_ccx(bcx).upcalls.malloc; }
122+
hp_shared { llupcall = bcx_ccx(bcx).upcalls.shared_malloc; }
71123
}
124+
125+
auto llresult = bcx.build.Call(llupcall, ~[bcx_fcx(bcx).lltaskptr, llsize,
126+
lltydescptr]);
127+
llresult = bcx.build.PointerCast(llresult, llptrty);
128+
bcx.build.Store(llresult, lldest);
72129
ret bcx;
73130
}
74131

75132

76133
// AST substructure translation, with destinations
77134

135+
fn trans_lit(&@block_ctxt cx, &dest dest, &ast::lit lit) -> @block_ctxt {
136+
auto bcx = cx;
137+
alt (lit.node) {
138+
ast::lit_str(?s, ast::sk_unique) {
139+
auto r = trans_lit_str_common(bcx_ccx(bcx), s);
140+
auto llstackpart = r._0; auto llheappartopt = r._1;
141+
bcx = store(bcx, dest, llstackpart, true);
142+
alt (llheappartopt) {
143+
none { /* no-op */ }
144+
some(?llheappart) {
145+
auto lldestptrptr =
146+
bcx.build.InBoundsGEP(dest_ptr(dest),
147+
~[tc::C_int(0),
148+
tc::C_uint(abi::ivec_elt_elems)]);
149+
auto llheappartty = lltype_of(llheappart);
150+
lldestptrptr =
151+
bcx.build.PointerCast(lldestptrptr,
152+
tc::T_ptr(tc::T_ptr(llheappartty)));
153+
malloc(bcx, lldestptrptr, hp_shared, none);
154+
auto lldestptr = bcx.build.Load(lldestptrptr);
155+
bcx.build.Store(llheappart, lldestptr);
156+
}
157+
}
158+
}
159+
_ {
160+
bcx = store(bcx, dest, trans_lit_common(bcx_ccx(bcx), lit), false);
161+
}
162+
}
163+
164+
ret bcx;
165+
}
166+
78167
fn trans_expr(&@block_ctxt bcx, &dest dest, &@ast::expr expr) -> @block_ctxt {
79-
ret bcx; // TODO
168+
alt (expr.node) {
169+
ast::expr_lit(?lit) { trans_lit(bcx, dest, *lit); ret bcx; }
170+
_ { fail "unhandled expr type in trans_expr"; }
171+
}
80172
}
81173

82174
fn trans_recv(&@block_ctxt bcx, &dest dest, &@ast::expr expr) -> @block_ctxt {
@@ -105,8 +197,83 @@ fn trans_block(&@block_ctxt cx, &dest dest, &ast::block block)
105197
}
106198

107199

200+
108201
// AST substructure translation, without destinations
109202

203+
// Common setup code shared between the crate-constant literal string case and
204+
// the block-local literal string case. We don't use destination-passing style
205+
// since that doesn't work for crate constants.
206+
fn trans_lit_str_common(&@crate_ctxt ccx, &str s)
207+
-> tup(ValueRef, option[ValueRef]) {
208+
auto len = str::byte_len(s);
209+
210+
auto array = ~[];
211+
for (u8 ch in s) { array += ~[tc::C_u8(ch as uint)]; }
212+
array += ~[tc::C_u8(0u)];
213+
214+
if len < abi::ivec_default_length - 1u { // minus 1 because of the \0
215+
while (ivec::len(array) < abi::ivec_default_length) {
216+
array += ~[tc::C_u8(0u)];
217+
}
218+
219+
ret tup(tc::C_struct(~[tc::C_uint(len + 1u),
220+
tc::C_uint(abi::ivec_default_length),
221+
tc::C_array(tc::T_i8(), array)]),
222+
none);
223+
}
224+
225+
auto llarray = tc::C_array(tc::T_i8(), array);
226+
ret tup(tc::C_struct(~[tc::C_uint(0u),
227+
tc::C_uint(abi::ivec_default_length),
228+
tc::C_null(tc::T_ptr(lltype_of(llarray)))]),
229+
some(llarray));
230+
}
231+
232+
// As above, we don't use destination-passing style here.
233+
fn trans_lit_common(&@crate_ctxt ccx, &ast::lit lit) -> ValueRef {
234+
alt (lit.node) {
235+
ast::lit_int(?i) { ret tc::C_int(i); }
236+
ast::lit_uint(?u) { ret tc::C_int(u as int); }
237+
ast::lit_mach_int(?tm, ?i) {
238+
// FIXME: the entire handling of mach types falls apart
239+
// if target int width is larger than host, at the moment;
240+
// re-do the mach-int types using 'big' when that works.
241+
242+
auto t = tc::T_int();
243+
auto s = LLTrue;
244+
alt (tm) {
245+
ast::ty_u8 { t = tc::T_i8(); s = LLFalse; }
246+
ast::ty_u16 { t = tc::T_i16(); s = LLFalse; }
247+
ast::ty_u32 { t = tc::T_i32(); s = LLFalse; }
248+
ast::ty_u64 { t = tc::T_i64(); s = LLFalse; }
249+
ast::ty_i8 { t = tc::T_i8(); }
250+
ast::ty_i16 { t = tc::T_i16(); }
251+
ast::ty_i32 { t = tc::T_i32(); }
252+
ast::ty_i64 { t = tc::T_i64(); }
253+
}
254+
ret tc::C_integral(t, i as uint, s);
255+
}
256+
ast::lit_float(?fs) { ret tc::C_float(fs); }
257+
ast::lit_mach_float(?tm, ?s) {
258+
auto t = tc::T_float();
259+
alt (tm) {
260+
ast::ty_f32 { t = tc::T_f32(); }
261+
ast::ty_f64 { t = tc::T_f64(); }
262+
}
263+
ret tc::C_floating(s, t);
264+
}
265+
ast::lit_char(?c) {
266+
ret tc::C_integral(tc::T_char(), c as uint, LLFalse);
267+
}
268+
ast::lit_bool(?b) { ret tc::C_bool(b); }
269+
ast::lit_nil { ret tc::C_nil(); }
270+
ast::lit_str(?s, ast::sk_rc) { ret tc::C_str(ccx, s); }
271+
ast::lit_str(?s, ast::sk_unique) {
272+
fail "unique str in trans_lit_common";
273+
}
274+
}
275+
}
276+
110277
fn trans_init_local(&@block_ctxt bcx, &@ast::local local) -> @block_ctxt {
111278
auto llptr = bcx_fcx(bcx).lllocals.get(local.node.id);
112279

@@ -129,7 +296,7 @@ fn trans_init_local(&@block_ctxt bcx, &@ast::local local) -> @block_ctxt {
129296
}
130297
none {
131298
ret store(bcx, dest_copy(bcx_tcx(bcx), llptr, t),
132-
trans_common::C_null(llelement_type(trans::val_ty(llptr))));
299+
tc::C_null(llelement_type(trans::val_ty(llptr))), false);
133300
}
134301
}
135302
}

0 commit comments

Comments
 (0)