@@ -191,20 +191,28 @@ type fn_ctxt =
191
191
// administrative activities that have to happen in only one place in
192
192
// the function, due to LLVM's quirks.
193
193
194
- // A block for all the function's allocas, so that LLVM will coalesce
195
- // them into a single alloca call.
196
- mutable BasicBlockRef llallocas ,
194
+ // A block for all the function's static allocas, so that LLVM will
195
+ // coalesce them into a single alloca call.
196
+ mutable BasicBlockRef llstaticallocas ,
197
197
198
198
// A block containing code that copies incoming arguments to space
199
- // already allocated by code in the llallocas block . (LLVM requires
200
- // that arguments be copied to local allocas before allowing most any
201
- // operation to be performed on them.)
199
+ // already allocated by code in one of the llallocas blocks . (LLVM
200
+ // requires that arguments be copied to local allocas before allowing
201
+ // most any operation to be performed on them.)
202
202
mutable BasicBlockRef llcopyargs ,
203
203
204
- // A block containing derived tydescs received from the runtime. See
205
- // description of derived_tydescs, below.
204
+ // The first block containing derived tydescs received from the
205
+ // runtime. See description of derived_tydescs, below.
206
+ mutable BasicBlockRef llderivedtydescs_first ,
207
+
208
+ // The last block of the llderivedtydescs group.
206
209
mutable BasicBlockRef llderivedtydescs ,
207
210
211
+ // A block for all of the dynamically sized allocas. This must be
212
+ // after llderivedtydescs, because these sometimes depend on
213
+ // information computed from derived tydescs.
214
+ mutable BasicBlockRef lldynamicallocas ,
215
+
208
216
// FIXME: Is llcopyargs actually the block containing the allocas for
209
217
// incoming function arguments? Or is it merely the block containing
210
218
// code that copies incoming args to space already alloca'd by code in
@@ -1173,11 +1181,11 @@ fn align_of(&@block_ctxt cx, &ty::t t) -> result {
1173
1181
}
1174
1182
1175
1183
fn alloca ( & @block_ctxt cx , TypeRef t) -> ValueRef {
1176
- ret new_builder ( cx. fcx . llallocas ) . Alloca ( t) ;
1184
+ ret new_builder ( cx. fcx . llstaticallocas ) . Alloca ( t) ;
1177
1185
}
1178
1186
1179
1187
fn array_alloca ( & @block_ctxt cx , TypeRef t, ValueRef n) -> ValueRef {
1180
- ret new_builder ( cx. fcx . llallocas ) . ArrayAlloca ( t, n) ;
1188
+ ret new_builder ( cx. fcx . lldynamicallocas ) . ArrayAlloca ( t, n) ;
1181
1189
}
1182
1190
1183
1191
@@ -3556,7 +3564,7 @@ mod ivec {
3556
3564
3557
3565
auto bcx;
3558
3566
if ( dynamic) {
3559
- bcx = llallocas_block_ctxt ( cx. fcx) ;
3567
+ bcx = llderivedtydescs_block_ctxt ( cx. fcx) ;
3560
3568
} else {
3561
3569
bcx = cx;
3562
3570
}
@@ -3565,26 +3573,25 @@ mod ivec {
3565
3573
auto rslt = size_of( bcx, unit_ty) ;
3566
3574
bcx = rslt. bcx;
3567
3575
llunitsz = rslt. val;
3568
- if ( dynamic) { bcx. fcx. llallocas = bcx. llbb; }
3576
+
3577
+ if ( dynamic) { cx. fcx. llderivedtydescs = bcx. llbb; }
3569
3578
3570
3579
auto llalen = bcx. build. Mul ( llunitsz,
3571
3580
C_uint ( abi:: ivec_default_length) ) ;
3572
3581
3573
3582
auto llptr;
3574
3583
auto llunitty = type_of_or_i8( bcx, unit_ty) ;
3584
+ auto bcx_result;
3575
3585
if ( dynamic) {
3576
3586
auto llarraysz = bcx. build. Add ( llsize_of( T_opaque_ivec ( ) ) ,
3577
3587
llalen) ;
3578
3588
auto llvecptr = array_alloca( bcx, T_i8 ( ) , llarraysz) ;
3579
- llptr = bcx. build. PointerCast ( llvecptr, T_ptr ( T_opaque_ivec ( ) ) ) ;
3580
- } else {
3581
- llptr = alloca( bcx, T_ivec ( llunitty) ) ;
3582
- }
3583
3589
3584
- auto bcx_result;
3585
- if ( dynamic) {
3586
3590
bcx_result = cx;
3591
+ llptr = bcx_result. build. PointerCast ( llvecptr,
3592
+ T_ptr ( T_opaque_ivec ( ) ) ) ;
3587
3593
} else {
3594
+ llptr = alloca( bcx, T_ivec ( llunitty) ) ;
3588
3595
bcx_result = bcx;
3589
3596
}
3590
3597
@@ -6753,27 +6760,51 @@ iter block_locals(&ast::block b) -> @ast::local {
6753
6760
}
6754
6761
}
6755
6762
6756
- fn llallocas_block_ctxt( & @fn_ctxt fcx) -> @block_ctxt {
6763
+ fn llstaticallocas_block_ctxt( & @fn_ctxt fcx) -> @block_ctxt {
6764
+ let vec[ cleanup] cleanups = [ ] ;
6765
+ ret @rec( llbb=fcx. llstaticallocas,
6766
+ build=new_builder( fcx. llstaticallocas) ,
6767
+ parent=parent_none,
6768
+ kind=SCOPE_BLOCK ,
6769
+ mutable cleanups=cleanups,
6770
+ sp=fcx. sp,
6771
+ fcx=fcx) ;
6772
+ }
6773
+
6774
+ fn llderivedtydescs_block_ctxt( & @fn_ctxt fcx) -> @block_ctxt {
6775
+ let vec[ cleanup] cleanups = [ ] ;
6776
+ ret @rec( llbb=fcx. llderivedtydescs,
6777
+ build=new_builder( fcx. llderivedtydescs) ,
6778
+ parent=parent_none,
6779
+ kind=SCOPE_BLOCK ,
6780
+ mutable cleanups=cleanups,
6781
+ sp=fcx. sp,
6782
+ fcx=fcx) ;
6783
+ }
6784
+
6785
+ fn lldynamicallocas_block_ctxt( & @fn_ctxt fcx) -> @block_ctxt {
6757
6786
let vec[ cleanup] cleanups = [ ] ;
6758
- ret @rec( llbb=fcx. llallocas ,
6759
- build=new_builder( fcx. llallocas ) ,
6787
+ ret @rec( llbb=fcx. lldynamicallocas ,
6788
+ build=new_builder( fcx. lldynamicallocas ) ,
6760
6789
parent=parent_none,
6761
6790
kind=SCOPE_BLOCK ,
6762
6791
mutable cleanups=cleanups,
6763
6792
sp=fcx. sp,
6764
6793
fcx=fcx) ;
6765
6794
}
6766
6795
6796
+
6797
+
6767
6798
fn alloc_ty( & @block_ctxt cx, & ty:: t t) -> result {
6768
6799
auto val = C_int ( 0 ) ;
6769
6800
if ( ty:: type_has_dynamic_size( cx. fcx. lcx. ccx. tcx, t) ) {
6770
6801
// NB: we have to run this particular 'size_of' in a
6771
- // block_ctxt built on the llallocas block for the fn,
6802
+ // block_ctxt built on the llderivedtydescs block for the fn,
6772
6803
// so that the size dominates the array_alloca that
6773
6804
// comes next.
6774
6805
6775
- auto n = size_of( llallocas_block_ctxt ( cx. fcx) , t) ;
6776
- cx. fcx. llallocas = n. bcx. llbb;
6806
+ auto n = size_of( llderivedtydescs_block_ctxt ( cx. fcx) , t) ;
6807
+ cx. fcx. llderivedtydescs = n. bcx. llbb;
6777
6808
val = array_alloca( cx, T_i8 ( ) , n. val) ;
6778
6809
} else { val = alloca( cx, type_of( cx. fcx. lcx. ccx, cx. sp, t) ) ; }
6779
6810
// NB: since we've pushed all size calculations in this
@@ -6862,13 +6893,14 @@ fn new_local_ctxt(&@crate_ctxt ccx) -> @local_ctxt {
6862
6893
}
6863
6894
6864
6895
6865
- // Creates the standard trio of basic blocks: allocas, copy- args, and derived
6866
- // tydescs.
6896
+ // Creates the standard quartet of basic blocks: static allocas, copy args,
6897
+ // derived tydescs, and dynamic allocas .
6867
6898
fn mk_standard_basic_blocks( ValueRef llfn) ->
6868
- tup( BasicBlockRef , BasicBlockRef , BasicBlockRef ) {
6869
- ret tup( llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "allocas ") ) ,
6899
+ tup( BasicBlockRef , BasicBlockRef , BasicBlockRef , BasicBlockRef ) {
6900
+ ret tup( llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "static_allocas ") ) ,
6870
6901
llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "copy_args") ) ,
6871
- llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "derived_tydescs") ) ) ;
6902
+ llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "derived_tydescs") ) ,
6903
+ llvm:: LLVMAppendBasicBlock ( llfn, str :: buf( "dynamic_allocas") ) ) ;
6872
6904
}
6873
6905
6874
6906
@@ -6893,9 +6925,11 @@ fn new_fn_ctxt(@local_ctxt cx, &span sp, ValueRef llfndecl) -> @fn_ctxt {
6893
6925
lltaskptr=lltaskptr,
6894
6926
llenv=llenv,
6895
6927
llretptr=llretptr,
6896
- mutable llallocas =llbbs. _0,
6928
+ mutable llstaticallocas =llbbs. _0,
6897
6929
mutable llcopyargs=llbbs. _1,
6930
+ mutable llderivedtydescs_first=llbbs. _2,
6898
6931
mutable llderivedtydescs=llbbs. _2,
6932
+ mutable lldynamicallocas=llbbs. _3,
6899
6933
mutable llself=none[ val_self_pair] ,
6900
6934
mutable lliterbody=none[ ValueRef ] ,
6901
6935
llargs=llargs,
@@ -6973,7 +7007,7 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx, ast::proto proto,
6973
7007
// allocas immediately upon entry; this permits us to GEP into structures we
6974
7008
// were passed and whatnot. Apparently mem2reg will mop up.
6975
7009
fn copy_any_self_to_alloca( @fn_ctxt fcx, option:: t[ ty_self_pair] ty_self) {
6976
- auto bcx = llallocas_block_ctxt ( fcx) ;
7010
+ auto bcx = llstaticallocas_block_ctxt ( fcx) ;
6977
7011
alt ( { fcx. llself } ) {
6978
7012
case ( some( ?pair) ) {
6979
7013
alt ( ty_self) {
@@ -7045,7 +7079,7 @@ fn ret_ty_of_fn(&@crate_ctxt ccx, ast::ann ann) -> ty::t {
7045
7079
}
7046
7080
7047
7081
fn populate_fn_ctxt_from_llself( @fn_ctxt fcx, val_self_pair llself) {
7048
- auto bcx = llallocas_block_ctxt ( fcx) ;
7082
+ auto bcx = llstaticallocas_block_ctxt ( fcx) ;
7049
7083
let vec[ ty:: t] field_tys = [ ] ;
7050
7084
for ( ast:: obj_field f in bcx. fcx. lcx. obj_fields) {
7051
7085
field_tys += [ node_ann_type( bcx. fcx. lcx. ccx, f. ann) ] ;
@@ -7088,20 +7122,22 @@ fn populate_fn_ctxt_from_llself(@fn_ctxt fcx, val_self_pair llself) {
7088
7122
i = 0 ;
7089
7123
for ( ast:: obj_field f in fcx. lcx. obj_fields) {
7090
7124
auto rslt = GEP_tup_like ( bcx, fields_tup_ty, obj_fields, [ 0 , i] ) ;
7091
- bcx = llallocas_block_ctxt ( fcx) ;
7125
+ bcx = llstaticallocas_block_ctxt ( fcx) ;
7092
7126
auto llfield = rslt. val;
7093
7127
fcx. llobjfields. insert( f. id, llfield) ;
7094
7128
i += 1 ;
7095
7129
}
7096
- fcx. llallocas = bcx. llbb;
7130
+ fcx. llstaticallocas = bcx. llbb;
7097
7131
}
7098
7132
7099
7133
7100
- // Ties up the llallocas -> llcopyargs -> llderivedtydescs -> lltop edges.
7134
+ // Ties up the llstaticallocas -> llcopyargs -> llderivedtydescs ->
7135
+ // lldynamicallocas -> lltop edges.
7101
7136
fn finish_fn( & @fn_ctxt fcx, BasicBlockRef lltop) {
7102
- new_builder( fcx. llallocas) . Br ( fcx. llcopyargs) ;
7103
- new_builder( fcx. llcopyargs) . Br ( fcx. llderivedtydescs) ;
7104
- new_builder( fcx. llderivedtydescs) . Br ( lltop) ;
7137
+ new_builder( fcx. llstaticallocas) . Br ( fcx. llcopyargs) ;
7138
+ new_builder( fcx. llcopyargs) . Br ( fcx. llderivedtydescs_first) ;
7139
+ new_builder( fcx. llderivedtydescs) . Br ( fcx. lldynamicallocas) ;
7140
+ new_builder( fcx. lldynamicallocas) . Br ( lltop) ;
7105
7141
}
7106
7142
7107
7143
0 commit comments