Skip to content

Commit 0561498

Browse files
committed
---
yaml --- r: 1260 b: refs/heads/master c: e922981 h: refs/heads/master v: v3
1 parent 62f98bc commit 0561498

File tree

3 files changed

+175
-16
lines changed

3 files changed

+175
-16
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: b86e8115d7489f2167942b32b9a62cdae3ef89b6
2+
refs/heads/master: e92298187bceb0cc1cf423dd37e0f5fe30359a17

trunk/src/comp/back/abi.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ fn memcpy_glue_name() -> str {
6363
ret "rust_memcpy_glue";
6464
}
6565

66+
fn bzero_glue_name() -> str {
67+
ret "rust_bzero_glue";
68+
}
69+
6670
fn upcall_glue_name(int n) -> str {
6771
ret "rust_upcall_" + util.common.istr(n);
6872
}

trunk/src/comp/middle/trans.rs

Lines changed: 170 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ type glue_fns = rec(ValueRef activate_glue,
5252
ValueRef exit_task_glue,
5353
vec[ValueRef] upcall_glues,
5454
ValueRef no_op_type_glue,
55-
ValueRef memcpy_glue);
55+
ValueRef memcpy_glue,
56+
ValueRef bzero_glue);
5657

5758
tag arity { nullary; n_ary; }
5859
type tag_info = rec(type_handle th,
@@ -632,19 +633,110 @@ fn find_scope_cx(@block_ctxt cx) -> @block_ctxt {
632633
}
633634
}
634635

635-
fn size_of(TypeRef t) -> ValueRef {
636+
fn umax(@block_ctxt cx, ValueRef a, ValueRef b) -> ValueRef {
637+
auto cond = cx.build.ICmp(lib.llvm.LLVMIntULT, a, b);
638+
ret cx.build.Select(cond, b, a);
639+
}
640+
641+
fn align_to(@block_ctxt cx, ValueRef off, ValueRef align) -> ValueRef {
642+
auto mask = cx.build.Sub(align, C_int(1));
643+
auto bumped = cx.build.Add(off, mask);
644+
ret cx.build.And(bumped, cx.build.Not(mask));
645+
}
646+
647+
fn llsize_of(TypeRef t) -> ValueRef {
636648
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMSizeOf(t), T_int(), False);
637649
}
638650

639-
fn align_of(TypeRef t) -> ValueRef {
651+
fn llalign_of(TypeRef t) -> ValueRef {
640652
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMAlignOf(t), T_int(), False);
641653
}
642654

655+
fn size_of(@block_ctxt cx, @ty.t t) -> ValueRef {
656+
if (!ty.type_has_dynamic_size(t)) {
657+
ret llsize_of(type_of(cx.fcx.ccx, t));
658+
}
659+
ret dynamic_size_of(cx, t);
660+
}
661+
662+
fn align_of(@block_ctxt cx, @ty.t t) -> ValueRef {
663+
if (!ty.type_has_dynamic_size(t)) {
664+
ret llalign_of(type_of(cx.fcx.ccx, t));
665+
}
666+
ret dynamic_align_of(cx, t);
667+
}
668+
669+
fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> ValueRef {
670+
alt (t.struct) {
671+
case (ty.ty_param(?p)) {
672+
auto szptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
673+
ret cx.build.Load(szptr);
674+
}
675+
case (ty.ty_tup(?elts)) {
676+
//
677+
// C padding rules:
678+
//
679+
//
680+
// - Pad after each element so that next element is aligned.
681+
// - Pad after final structure member so that whole structure
682+
// is aligned to max alignment of interior.
683+
//
684+
auto off = C_int(0);
685+
auto max_align = C_int(1);
686+
for (@ty.t e in elts) {
687+
auto elt_align = align_of(cx, e);
688+
auto elt_size = size_of(cx, e);
689+
auto aligned_off = align_to(cx, off, elt_align);
690+
off = cx.build.Add(aligned_off, elt_size);
691+
max_align = umax(cx, max_align, elt_align);
692+
}
693+
off = align_to(cx, off, max_align);
694+
ret off;
695+
}
696+
case (ty.ty_rec(?flds)) {
697+
auto off = C_int(0);
698+
auto max_align = C_int(1);
699+
for (ty.field f in flds) {
700+
auto elt_align = align_of(cx, f.ty);
701+
auto elt_size = size_of(cx, f.ty);
702+
auto aligned_off = align_to(cx, off, elt_align);
703+
off = cx.build.Add(aligned_off, elt_size);
704+
max_align = umax(cx, max_align, elt_align);
705+
}
706+
off = align_to(cx, off, max_align);
707+
ret off;
708+
}
709+
}
710+
}
711+
712+
fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> ValueRef {
713+
alt (t.struct) {
714+
case (ty.ty_param(?p)) {
715+
auto aptr = field_of_tydesc(cx, t, abi.tydesc_field_align);
716+
ret cx.build.Load(aptr);
717+
}
718+
case (ty.ty_tup(?elts)) {
719+
auto a = C_int(1);
720+
for (@ty.t e in elts) {
721+
a = umax(cx, a, align_of(cx, e));
722+
}
723+
ret a;
724+
}
725+
case (ty.ty_rec(?flds)) {
726+
auto a = C_int(1);
727+
for (ty.field f in flds) {
728+
a = umax(cx, a, align_of(cx, f.ty));
729+
}
730+
ret a;
731+
}
732+
}
733+
}
734+
643735
fn trans_malloc_inner(@block_ctxt cx, TypeRef llptr_ty) -> result {
644736
auto llbody_ty = lib.llvm.llvm.LLVMGetElementType(llptr_ty);
645737
// FIXME: need a table to collect tydesc globals.
646738
auto tydesc = C_int(0);
647-
auto sz = size_of(llbody_ty);
739+
auto sz = llsize_of(llbody_ty);
648740
auto sub = trans_upcall(cx, "upcall_malloc", vec(sz, tydesc));
649741
sub.val = sub.bcx.build.IntToPtr(sub.val, llptr_ty);
650742
ret sub;
@@ -699,8 +791,8 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t) {
699791
auto pvoid = T_ptr(T_i8());
700792
auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), pvoid), T_void()));
701793
auto tydesc = C_struct(vec(C_null(pvoid),
702-
size_of(llty),
703-
align_of(llty),
794+
llsize_of(llty),
795+
llalign_of(llty),
704796
take_glue, // take_glue_off
705797
drop_glue, // drop_glue_off
706798
C_null(glue_fn_ty), // free_glue_off
@@ -1146,7 +1238,7 @@ fn iter_sequence(@block_ctxt cx,
11461238
C_int(abi.vec_elt_fill)));
11471239

11481240
auto llunit_ty = type_of(cx.fcx.ccx, elt_ty);
1149-
auto unit_sz = size_of(llunit_ty);
1241+
auto unit_sz = size_of(cx, elt_ty);
11501242

11511243
auto len = cx.build.Load(lenptr);
11521244
if (trailing_null) {
@@ -1249,6 +1341,15 @@ fn call_memcpy(@block_ctxt cx,
12491341
vec(dst_ptr, src_ptr, size)));
12501342
}
12511343

1344+
fn call_bzero(@block_ctxt cx,
1345+
ValueRef dst,
1346+
ValueRef n_bytes) -> result {
1347+
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
1348+
auto size = cx.build.IntCast(n_bytes, T_int());
1349+
ret res(cx, cx.build.FastCall(cx.fcx.ccx.glues.bzero_glue,
1350+
vec(dst_ptr, size)));
1351+
}
1352+
12521353
fn memcpy_ty(@block_ctxt cx,
12531354
ValueRef dst,
12541355
ValueRef src,
@@ -1901,7 +2002,7 @@ impure fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
19012002
auto v = lv.val;
19022003

19032004
auto llunit_ty = node_type(cx.fcx.ccx, ann);
1904-
auto unit_sz = size_of(llunit_ty);
2005+
auto unit_sz = size_of(cx, node_ann_type(cx.fcx.ccx, ann));
19052006
auto scaled_ix = ix.bcx.build.Mul(ix.val, unit_sz);
19062007

19072008
auto lim = ix.bcx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_fill)));
@@ -2374,7 +2475,7 @@ impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
23742475
}
23752476

23762477
auto llunit_ty = type_of(cx.fcx.ccx, unit_ty);
2377-
auto unit_sz = size_of(llunit_ty);
2478+
auto unit_sz = size_of(cx, unit_ty);
23782479
auto data_sz = llvm.LLVMConstMul(C_int(_vec.len[@ast.expr](args) as int),
23792480
unit_sz);
23802481

@@ -2681,9 +2782,15 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
26812782
sub = copy_ty(sub.bcx, true, llptr, sub.val, ty);
26822783
}
26832784
case (_) {
2684-
auto llty = type_of(cx.fcx.ccx, ty);
2685-
auto null = lib.llvm.llvm.LLVMConstNull(llty);
2686-
sub = res(cx, cx.build.Store(null, llptr));
2785+
if (middle.ty.type_has_dynamic_size(ty)) {
2786+
auto llsz = size_of(cx, ty);
2787+
sub = call_bzero(cx, llptr, llsz);
2788+
2789+
} else {
2790+
auto llty = type_of(cx.fcx.ccx, ty);
2791+
auto null = lib.llvm.llvm.LLVMConstNull(llty);
2792+
sub = res(cx, cx.build.Store(null, llptr));
2793+
}
26872794
}
26882795
}
26892796
}
@@ -2779,8 +2886,14 @@ impure fn trans_block(@block_ctxt cx, &ast.block b) -> result {
27792886
auto bcx = cx;
27802887

27812888
for each (@ast.local local in block_locals(b)) {
2782-
auto ty = node_type(cx.fcx.ccx, local.ann);
2783-
auto val = bcx.build.Alloca(ty);
2889+
auto t = node_ann_type(cx.fcx.ccx, local.ann);
2890+
auto val = C_int(0);
2891+
if (ty.type_has_dynamic_size(t)) {
2892+
auto n = size_of(bcx, t);
2893+
val = bcx.build.ArrayAlloca(T_i8(), n);
2894+
} else {
2895+
val = bcx.build.Alloca(type_of(cx.fcx.ccx, t));
2896+
}
27842897
cx.fcx.lllocals.insert(local.id, val);
27852898
}
27862899
auto r = res(bcx, C_nil());
@@ -3684,6 +3797,47 @@ fn make_memcpy_glue(ModuleRef llmod) -> ValueRef {
36843797
ret fun;
36853798
}
36863799

3800+
fn make_bzero_glue(ModuleRef llmod) -> ValueRef {
3801+
3802+
// We're not using the LLVM memset intrinsic. Same as with memcpy.
3803+
3804+
auto p8 = T_ptr(T_i8());
3805+
3806+
auto ty = T_fn(vec(p8, T_int()), T_void());
3807+
auto fun = decl_fastcall_fn(llmod, abi.bzero_glue_name(), ty);
3808+
3809+
auto initbb = llvm.LLVMAppendBasicBlock(fun, _str.buf("init"));
3810+
auto hdrbb = llvm.LLVMAppendBasicBlock(fun, _str.buf("hdr"));
3811+
auto loopbb = llvm.LLVMAppendBasicBlock(fun, _str.buf("loop"));
3812+
auto endbb = llvm.LLVMAppendBasicBlock(fun, _str.buf("end"));
3813+
3814+
auto dst = llvm.LLVMGetParam(fun, 0u);
3815+
auto count = llvm.LLVMGetParam(fun, 1u);
3816+
3817+
// Init block.
3818+
auto ib = new_builder(initbb);
3819+
auto ip = ib.Alloca(T_int());
3820+
ib.Store(C_int(0), ip);
3821+
ib.Br(hdrbb);
3822+
3823+
// Loop-header block
3824+
auto hb = new_builder(hdrbb);
3825+
auto i = hb.Load(ip);
3826+
hb.CondBr(hb.ICmp(lib.llvm.LLVMIntEQ, count, i), endbb, loopbb);
3827+
3828+
// Loop-body block
3829+
auto lb = new_builder(loopbb);
3830+
i = lb.Load(ip);
3831+
lb.Store(C_integral(0, T_i8()), lb.GEP(dst, vec(i)));
3832+
lb.Store(lb.Add(i, C_int(1)), ip);
3833+
lb.Br(hdrbb);
3834+
3835+
// End block
3836+
auto eb = new_builder(endbb);
3837+
eb.RetVoid();
3838+
ret fun;
3839+
}
3840+
36873841
fn make_glues(ModuleRef llmod) -> @glue_fns {
36883842
ret @rec(activate_glue = decl_glue(llmod, abi.activate_glue_name()),
36893843
yield_glue = decl_glue(llmod, abi.yield_glue_name()),
@@ -3704,7 +3858,8 @@ fn make_glues(ModuleRef llmod) -> @glue_fns {
37043858
_vec.init_fn[ValueRef](bind decl_upcall(llmod, _),
37053859
abi.n_upcall_glues as uint),
37063860
no_op_type_glue = make_no_op_type_glue(llmod),
3707-
memcpy_glue = make_memcpy_glue(llmod));
3861+
memcpy_glue = make_memcpy_glue(llmod),
3862+
bzero_glue = make_bzero_glue(llmod));
37083863
}
37093864

37103865
fn trans_crate(session.session sess, @ast.crate crate, str output,

0 commit comments

Comments
 (0)