From bf5840d530ab0b96e0f760728d13cf16cd7c334e Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 14 Jun 2011 11:54:09 -0700 Subject: [PATCH] rustc: Do a dynamic alloca for generic interior vectors; fix data pointer calculation when spilling vectors --- src/comp/back/abi.rs | 1 - src/comp/middle/trans.rs | 29 ++++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 42a4dddd564..e1fb2f00d91 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -66,7 +66,6 @@ const int closure_elt_bindings = 2; const int closure_elt_ty_params = 3; -const uint ivec_default_size = 64u; const uint ivec_default_length = 8u; const uint ivec_elt_len = 0u; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index cee4cb2911c..21097d5addc 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -581,7 +581,7 @@ fn T_ivec(TypeRef t) -> TypeRef { fn T_opaque_ivec() -> TypeRef { ret T_struct([T_int(), // Length ("fill"; if zero, heapified) T_int(), // Alloc - T_array(T_i8(), abi::ivec_default_size)]); // Body elements + T_array(T_i8(), 0u)]); // Body elements } fn T_ivec_heap_part(TypeRef t) -> TypeRef { @@ -3728,7 +3728,9 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v, C_int(0)]); auto heap_len = on_heap_cx.build.Load(heap_len_ptr); auto new_heap_len = on_heap_cx.build.Add(heap_len, len_needed); - auto heap_no_resize_needed = on_heap_cx.build.ICmp(lib::llvm::LLVMIntULT, + auto heap_len_unscaled = on_heap_cx.build.UDiv(heap_len, + llsize_of(llunitty)); + auto heap_no_resize_needed = on_heap_cx.build.ICmp(lib::llvm::LLVMIntULE, new_heap_len, alen); auto heap_no_resize_cx = new_sub_block_ctxt(cx, "heap_no_resize"); auto heap_resize_cx = new_sub_block_ctxt(cx, "heap_resize"); @@ -3736,8 +3738,6 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v, heap_resize_cx.llbb); // Case (1): We're on the heap and don't need to resize. - auto heap_len_unscaled = heap_no_resize_cx.build.UDiv(heap_len, - llsize_of(llunitty)); auto heap_data_no_resize = heap_no_resize_cx.build.InBoundsGEP(heap_ptr, [C_int(0), C_uint(abi::ivec_heap_elt_elems), heap_len_unscaled]); heap_no_resize_cx.build.Br(next_cx.llbb); @@ -3754,21 +3754,21 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v, heap_resize_cx.build.InBoundsGEP(stub_ptr, [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)])); auto heap_data_resize = heap_resize_cx.build.InBoundsGEP(heap_ptr_resize, - [C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]); + [C_int(0), C_uint(abi::ivec_heap_elt_elems), heap_len_unscaled]); heap_resize_cx.build.Br(next_cx.llbb); // We're on the stack. Check whether we need to spill to the heap. auto new_stack_len = on_stack_cx.build.Add(stack_len, len_needed); - auto stack_no_spill_needed = on_stack_cx.build.ICmp(lib::llvm::LLVMIntULT, + auto stack_no_spill_needed = on_stack_cx.build.ICmp(lib::llvm::LLVMIntULE, new_stack_len, alen); + auto stack_len_unscaled = on_stack_cx.build.UDiv(stack_len, + llsize_of(llunitty)); auto stack_no_spill_cx = new_sub_block_ctxt(cx, "stack_no_spill"); auto stack_spill_cx = new_sub_block_ctxt(cx, "stack_spill"); on_stack_cx.build.CondBr(stack_no_spill_needed, stack_no_spill_cx.llbb, stack_spill_cx.llbb); // Case (3): We're on the stack and don't need to spill. - auto stack_len_unscaled = stack_no_spill_cx.build.UDiv(stack_len, - llsize_of(llunitty)); auto stack_data_no_spill = stack_no_spill_cx.build.InBoundsGEP(v, [C_int(0), C_uint(abi::ivec_elt_elems), stack_len_unscaled]); stack_no_spill_cx.build.Br(next_cx.llbb); @@ -3789,7 +3789,7 @@ fn reserve_ivec_space(&@block_ctxt cx, TypeRef llunitty, ValueRef v, auto heap_len_ptr_spill = stack_spill_cx.build.InBoundsGEP(heap_ptr_spill, [C_int(0), C_uint(abi::ivec_heap_elt_len)]); auto heap_data_spill = stack_spill_cx.build.InBoundsGEP(heap_ptr_spill, - [C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]); + [C_int(0), C_uint(abi::ivec_heap_elt_elems), stack_len_unscaled]); stack_spill_cx.build.Br(next_cx.llbb); @@ -5840,10 +5840,14 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann) auto unit_align = rslt.val; bcx = rslt.bcx; + auto llalen = bcx.build.Mul(unit_align, C_uint(abi::ivec_default_length)); + auto llunitty = type_of_or_i8(bcx, unit_ty); auto llvecptr; if (ty::type_has_dynamic_size(bcx.fcx.lcx.ccx.tcx, unit_ty)) { - llvecptr = alloca(bcx, T_opaque_ivec()); + auto array_size = bcx.build.Add(llsize_of(T_opaque_ivec()), llalen); + llvecptr = array_alloca(bcx, T_i8(), array_size); + llvecptr = bcx.build.PointerCast(llvecptr, T_ptr(T_opaque_ivec())); } else { llvecptr = alloca(bcx, T_ivec(llunitty)); } @@ -5852,12 +5856,11 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann) // Allocate the vector pieces and store length and allocated length. auto llfirsteltptr; - if (vec::len(args) > 0u && vec::len(args) < abi::ivec_default_size) { + if (vec::len(args) > 0u && vec::len(args) < abi::ivec_default_length) { // Interior case. bcx.build.Store(lllen, bcx.build.InBoundsGEP(llvecptr, [C_int(0), C_uint(abi::ivec_elt_len)])); - bcx.build.Store(C_uint(abi::ivec_default_size), - bcx.build.InBoundsGEP(llvecptr, + bcx.build.Store(llalen, bcx.build.InBoundsGEP(llvecptr, [C_int(0), C_uint(abi::ivec_elt_alen)])); llfirsteltptr = bcx.build.InBoundsGEP(llvecptr, [C_int(0), C_uint(abi::ivec_elt_elems), C_int(0)]); -- GitLab