Skip to content

Commit bf5840d

Browse files
committed
rustc: Do a dynamic alloca for generic interior vectors; fix data pointer calculation when spilling vectors
1 parent 206429e commit bf5840d

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

src/comp/back/abi.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ const int closure_elt_target = 1;
6666
const int closure_elt_bindings = 2;
6767
const int closure_elt_ty_params = 3;
6868

69-
const uint ivec_default_size = 64u;
7069
const uint ivec_default_length = 8u;
7170

7271
const uint ivec_elt_len = 0u;

src/comp/middle/trans.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ fn T_ivec(TypeRef t) -> TypeRef {
581581
fn T_opaque_ivec() -> TypeRef {
582582
ret T_struct([T_int(), // Length ("fill"; if zero, heapified)
583583
T_int(), // Alloc
584-
T_array(T_i8(), abi::ivec_default_size)]); // Body elements
584+
T_array(T_i8(), 0u)]); // Body elements
585585
}
586586

587587
fn T_ivec_heap_part(TypeRef t) -> TypeRef {
@@ -3728,16 +3728,16 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v,
37283728
C_int(0)]);
37293729
auto heap_len = on_heap_cx.build.Load(heap_len_ptr);
37303730
auto new_heap_len = on_heap_cx.build.Add(heap_len, len_needed);
3731-
auto heap_no_resize_needed = on_heap_cx.build.ICmp(lib::llvm::LLVMIntULT,
3731+
auto heap_len_unscaled = on_heap_cx.build.UDiv(heap_len,
3732+
llsize_of(llunitty));
3733+
auto heap_no_resize_needed = on_heap_cx.build.ICmp(lib::llvm::LLVMIntULE,
37323734
new_heap_len, alen);
37333735
auto heap_no_resize_cx = new_sub_block_ctxt(cx, "heap_no_resize");
37343736
auto heap_resize_cx = new_sub_block_ctxt(cx, "heap_resize");
37353737
on_heap_cx.build.CondBr(heap_no_resize_needed, heap_no_resize_cx.llbb,
37363738
heap_resize_cx.llbb);
37373739

37383740
// Case (1): We're on the heap and don't need to resize.
3739-
auto heap_len_unscaled = heap_no_resize_cx.build.UDiv(heap_len,
3740-
llsize_of(llunitty));
37413741
auto heap_data_no_resize = heap_no_resize_cx.build.InBoundsGEP(heap_ptr,
37423742
[C_int(0), C_uint(abi::ivec_heap_elt_elems), heap_len_unscaled]);
37433743
heap_no_resize_cx.build.Br(next_cx.llbb);
@@ -3754,21 +3754,21 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v,
37543754
heap_resize_cx.build.InBoundsGEP(stub_ptr,
37553755
[C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)]));
37563756
auto heap_data_resize = heap_resize_cx.build.InBoundsGEP(heap_ptr_resize,
3757-
[C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]);
3757+
[C_int(0), C_uint(abi::ivec_heap_elt_elems), heap_len_unscaled]);
37583758
heap_resize_cx.build.Br(next_cx.llbb);
37593759

37603760
// We're on the stack. Check whether we need to spill to the heap.
37613761
auto new_stack_len = on_stack_cx.build.Add(stack_len, len_needed);
3762-
auto stack_no_spill_needed = on_stack_cx.build.ICmp(lib::llvm::LLVMIntULT,
3762+
auto stack_no_spill_needed = on_stack_cx.build.ICmp(lib::llvm::LLVMIntULE,
37633763
new_stack_len, alen);
3764+
auto stack_len_unscaled = on_stack_cx.build.UDiv(stack_len,
3765+
llsize_of(llunitty));
37643766
auto stack_no_spill_cx = new_sub_block_ctxt(cx, "stack_no_spill");
37653767
auto stack_spill_cx = new_sub_block_ctxt(cx, "stack_spill");
37663768
on_stack_cx.build.CondBr(stack_no_spill_needed, stack_no_spill_cx.llbb,
37673769
stack_spill_cx.llbb);
37683770

37693771
// Case (3): We're on the stack and don't need to spill.
3770-
auto stack_len_unscaled = stack_no_spill_cx.build.UDiv(stack_len,
3771-
llsize_of(llunitty));
37723772
auto stack_data_no_spill = stack_no_spill_cx.build.InBoundsGEP(v,
37733773
[C_int(0), C_uint(abi::ivec_elt_elems), stack_len_unscaled]);
37743774
stack_no_spill_cx.build.Br(next_cx.llbb);
@@ -3789,7 +3789,7 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v,
37893789
auto heap_len_ptr_spill = stack_spill_cx.build.InBoundsGEP(heap_ptr_spill,
37903790
[C_int(0), C_uint(abi::ivec_heap_elt_len)]);
37913791
auto heap_data_spill = stack_spill_cx.build.InBoundsGEP(heap_ptr_spill,
3792-
[C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]);
3792+
[C_int(0), C_uint(abi::ivec_heap_elt_elems), stack_len_unscaled]);
37933793

37943794
stack_spill_cx.build.Br(next_cx.llbb);
37953795

@@ -5840,10 +5840,14 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
58405840
auto unit_align = rslt.val;
58415841
bcx = rslt.bcx;
58425842

5843+
auto llalen = bcx.build.Mul(unit_align, C_uint(abi::ivec_default_length));
5844+
58435845
auto llunitty = type_of_or_i8(bcx, unit_ty);
58445846
auto llvecptr;
58455847
if (ty::type_has_dynamic_size(bcx.fcx.lcx.ccx.tcx, unit_ty)) {
5846-
llvecptr = alloca(bcx, T_opaque_ivec());
5848+
auto array_size = bcx.build.Add(llsize_of(T_opaque_ivec()), llalen);
5849+
llvecptr = array_alloca(bcx, T_i8(), array_size);
5850+
llvecptr = bcx.build.PointerCast(llvecptr, T_ptr(T_opaque_ivec()));
58475851
} else {
58485852
llvecptr = alloca(bcx, T_ivec(llunitty));
58495853
}
@@ -5852,12 +5856,11 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
58525856

58535857
// Allocate the vector pieces and store length and allocated length.
58545858
auto llfirsteltptr;
5855-
if (vec::len(args) > 0u && vec::len(args) < abi::ivec_default_size) {
5859+
if (vec::len(args) > 0u && vec::len(args) < abi::ivec_default_length) {
58565860
// Interior case.
58575861
bcx.build.Store(lllen, bcx.build.InBoundsGEP(llvecptr,
58585862
[C_int(0), C_uint(abi::ivec_elt_len)]));
5859-
bcx.build.Store(C_uint(abi::ivec_default_size),
5860-
bcx.build.InBoundsGEP(llvecptr,
5863+
bcx.build.Store(llalen, bcx.build.InBoundsGEP(llvecptr,
58615864
[C_int(0), C_uint(abi::ivec_elt_alen)]));
58625865
llfirsteltptr = bcx.build.InBoundsGEP(llvecptr,
58635866
[C_int(0), C_uint(abi::ivec_elt_elems), C_int(0)]);

0 commit comments

Comments
 (0)