@@ -2627,34 +2627,34 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args,
2627
2627
jl_value_t *ety = jl_tparam0 (aty_dt);
2628
2628
if (!jl_has_free_typevars (ety)) { // TODO: jn/foreigncall branch has a better predicate
2629
2629
size_t elsz, al;
2630
- if (!jl_islayout_inline (ety, &elsz, &al))
2630
+ int isboxed = !jl_islayout_inline (ety, &elsz, &al);
2631
+ if (isboxed)
2631
2632
ety = (jl_value_t *)jl_any_type;
2632
2633
jl_value_t *ndp = jl_tparam1 (aty_dt);
2633
2634
if (jl_is_long (ndp) || nargs==2 ) {
2634
2635
jl_cgval_t ary = emit_expr (args[1 ], ctx);
2635
2636
ssize_t nd = jl_is_long (ndp) ? jl_unbox_long (ndp) : -1 ;
2636
2637
Value *idx = emit_array_nd_index (ary, args[1 ], nd, &args[2 ], nargs-1 , ctx);
2637
- if (jl_array_store_unboxed (ety) &&
2638
- jl_datatype_size (ety) == 0 ) {
2639
- assert (jl_is_datatype (ety));
2640
- assert (((jl_datatype_t *)ety)->instance != NULL );
2641
- *ret = ghostValue (ety);
2642
- }
2643
- else if (jl_is_uniontype (ety)) {
2644
- Type *AT = ArrayType::get (IntegerType::get (jl_LLVMContext, 8 * al), (elsz + al - 1 ) / al);
2645
- AllocaInst *lv = emit_static_alloca (AT, ctx);
2646
- if (al > 1 )
2647
- lv->setAlignment (al);
2638
+ if (!isboxed && jl_is_uniontype (ety)) {
2648
2639
Value *nbytes = ConstantInt::get (T_size, elsz);
2649
2640
Value *data = emit_arrayptr (ary, args[1 ], ctx);
2650
- Value *elidx = builder.CreateMul (idx, nbytes);
2651
- builder.CreateMemCpy (lv, builder.CreateGEP (T_int8, data, elidx), nbytes, al);
2652
2641
Value *selidx = builder.CreateMul (emit_arraymaxsize_prim (ary, ctx), nbytes);
2653
2642
selidx = builder.CreateAdd (selidx, idx);
2654
2643
Value *ptindex = builder.CreateGEP (T_int8, data, selidx);
2655
2644
Value *tindex = builder.CreateNUWAdd (ConstantInt::get (T_int8, 1 ), builder.CreateLoad (T_int8, ptindex));
2645
+ Type *AT = ArrayType::get (IntegerType::get (jl_LLVMContext, 8 * al), (elsz + al - 1 ) / al);
2646
+ AllocaInst *lv = emit_static_alloca (AT, ctx);
2647
+ if (al > 1 )
2648
+ lv->setAlignment (al);
2649
+ Value *elidx = builder.CreateMul (idx, nbytes);
2650
+ builder.CreateMemCpy (lv, builder.CreateGEP (T_int8, data, elidx), nbytes, al);
2656
2651
*ret = mark_julia_slot (lv, ety, tindex, tbaa_stack);
2657
2652
}
2653
+ else if (!isboxed && jl_datatype_size (ety) == 0 ){
2654
+ assert (jl_is_datatype (ety));
2655
+ assert (((jl_datatype_t *)ety)->instance != NULL );
2656
+ *ret = ghostValue (ety);
2657
+ }
2658
2658
else {
2659
2659
*ret = typed_load (emit_arrayptr (ary, args[1 ], ctx), idx, ety, ctx,
2660
2660
jl_array_store_unboxed (ety) ? tbaa_arraybuf : tbaa_ptrarraybuf);
@@ -2689,68 +2689,74 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args,
2689
2689
jl_cgval_t ary = emit_expr (args[1 ], ctx);
2690
2690
ssize_t nd = jl_is_long (ndp) ? jl_unbox_long (ndp) : -1 ;
2691
2691
Value *idx = emit_array_nd_index (ary, args[1 ], nd, &args[3 ], nargs-2 , ctx);
2692
- if (!isboxed && jl_datatype_size (ety) == 0 ) {
2692
+ jl_cgval_t rhs = emit_expr (args[2 ], ctx);
2693
+ PHINode *data_owner = NULL ; // owner object against which the write barrier must check
2694
+ if (isboxed) { // if not boxed we don't need a write barrier
2695
+ assert (ary.isboxed );
2696
+ Value *aryv = maybe_decay_untracked (boxed (ary, ctx));
2697
+ Value *flags = emit_arrayflags (ary, ctx);
2698
+ // the owner of the data is ary itself except if ary->how == 3
2699
+ flags = builder.CreateAnd (flags, 3 );
2700
+ Value *is_owned = builder.CreateICmpEQ (flags, ConstantInt::get (T_int16, 3 ));
2701
+ BasicBlock *curBB = builder.GetInsertBlock ();
2702
+ BasicBlock *ownedBB = BasicBlock::Create (jl_LLVMContext, " array_owned" , ctx->f );
2703
+ BasicBlock *mergeBB = BasicBlock::Create (jl_LLVMContext, " merge_own" , ctx->f );
2704
+ builder.CreateCondBr (is_owned, ownedBB, mergeBB);
2705
+ builder.SetInsertPoint (ownedBB);
2706
+ // load owner pointer
2707
+ Value *own_ptr;
2708
+ if (jl_is_long (ndp)) {
2709
+ own_ptr = tbaa_decorate (tbaa_const, builder.CreateLoad (
2710
+ emit_bitcast (
2711
+ builder.CreateConstGEP1_32 (
2712
+ emit_bitcast (decay_derived (aryv), T_pint8),
2713
+ jl_array_data_owner_offset (nd)),
2714
+ T_pprjlvalue)));
2715
+ }
2716
+ else {
2717
+ own_ptr = builder.CreateCall (
2718
+ prepare_call (jlarray_data_owner_func),
2719
+ {aryv});
2720
+ }
2721
+ builder.CreateBr (mergeBB);
2722
+ builder.SetInsertPoint (mergeBB);
2723
+ data_owner = builder.CreatePHI (T_prjlvalue, 2 );
2724
+ data_owner->addIncoming (aryv, curBB);
2725
+ data_owner->addIncoming (own_ptr, ownedBB);
2726
+ }
2727
+ else if (jl_datatype_size (ety) == 0 ) {
2693
2728
// no-op, but emit expr for possible effects
2694
2729
assert (jl_is_datatype (ety));
2695
2730
emit_expr (args[2 ], ctx);
2696
2731
}
2697
- else {
2698
- jl_cgval_t rhs = emit_expr (args[2 ], ctx);
2699
- PHINode *data_owner = NULL ; // owner object against which the write barrier must check
2700
- if (isboxed) { // if not boxed we don't need a write barrier
2701
- assert (ary.isboxed );
2702
- Value *aryv = maybe_decay_untracked (boxed (ary, ctx));
2703
- Value *flags = emit_arrayflags (ary, ctx);
2704
- // the owner of the data is ary itself except if ary->how == 3
2705
- flags = builder.CreateAnd (flags, 3 );
2706
- Value *is_owned = builder.CreateICmpEQ (flags, ConstantInt::get (T_int16, 3 ));
2707
- BasicBlock *curBB = builder.GetInsertBlock ();
2708
- BasicBlock *ownedBB = BasicBlock::Create (jl_LLVMContext, " array_owned" , ctx->f );
2709
- BasicBlock *mergeBB = BasicBlock::Create (jl_LLVMContext, " merge_own" , ctx->f );
2710
- builder.CreateCondBr (is_owned, ownedBB, mergeBB);
2711
- builder.SetInsertPoint (ownedBB);
2712
- // load owner pointer
2713
- Value *own_ptr;
2714
- if (jl_is_long (ndp)) {
2715
- own_ptr = tbaa_decorate (tbaa_const, builder.CreateLoad (
2716
- emit_bitcast (
2717
- builder.CreateConstGEP1_32 (
2718
- emit_bitcast (decay_derived (aryv), T_pint8),
2719
- jl_array_data_owner_offset (nd)),
2720
- T_pprjlvalue)));
2721
- }
2722
- else {
2723
- own_ptr = builder.CreateCall (
2724
- prepare_call (jlarray_data_owner_func),
2725
- {aryv});
2726
- }
2727
- builder.CreateBr (mergeBB);
2728
- builder.SetInsertPoint (mergeBB);
2729
- data_owner = builder.CreatePHI (T_prjlvalue, 2 );
2730
- data_owner->addIncoming (aryv, curBB);
2731
- data_owner->addIncoming (own_ptr, ownedBB);
2732
+ else if (jl_is_uniontype (ety)) {
2733
+ Value *nbytes = ConstantInt::get (T_size, elsz);
2734
+ Value *data = emit_arrayptr (ary, args[1 ], ctx);
2735
+ // compute tindex from rhs
2736
+ jl_cgval_t rhs_union = convert_julia_type (rhs, ety, ctx);
2737
+ Value *tindex = compute_tindex_unboxed (rhs_union, ety, ctx);
2738
+ tindex = builder.CreateNUWSub (tindex, ConstantInt::get (T_int8, 1 ));
2739
+ Value *selidx = builder.CreateMul (emit_arraymaxsize_prim (ary, ctx), nbytes);
2740
+ selidx = builder.CreateAdd (selidx, idx);
2741
+ Value *ptindex = builder.CreateGEP (T_int8, data, selidx);
2742
+ builder.CreateStore (tindex, ptindex);
2743
+ if (jl_datatype_size ((jl_datatype_t *)jl_typeof (args[2 ])) == 0 ) {
2744
+ // no-op, but emit expr for possible effects
2745
+ assert (jl_is_datatype (ety));
2746
+ emit_expr (args[2 ], ctx);
2732
2747
}
2733
- if ( jl_is_uniontype (ety)) {
2748
+ else {
2734
2749
// copy data
2735
- Value *nbytes = ConstantInt::get (T_size, elsz);
2736
- Value *data = emit_arrayptr (ary, args[1 ], ctx);
2737
2750
Value *elidx = builder.CreateMul (idx, nbytes);
2738
2751
Value *addr = builder.CreateGEP (T_int8, data, elidx);
2739
2752
emit_unionmove (addr, rhs, NULL , false , NULL , ctx);
2740
- // compute tindex from rhs
2741
- jl_cgval_t rhs_union = convert_julia_type (rhs, ety, ctx);
2742
- Value *tindex = compute_tindex_unboxed (rhs_union, ety, ctx);
2743
- tindex = builder.CreateNUWSub (tindex, ConstantInt::get (T_int8, 1 ));
2744
- Value *selidx = builder.CreateMul (emit_arraymaxsize_prim (ary, ctx), nbytes);
2745
- selidx = builder.CreateAdd (selidx, idx);
2746
- Value *ptindex = builder.CreateGEP (T_int8, data, selidx);
2747
- builder.CreateStore (tindex, ptindex);
2748
- } else {
2749
- typed_store (emit_arrayptr (ary, args[1 ], ctx, isboxed), idx, rhs,
2750
- ety, ctx, !isboxed ? tbaa_arraybuf : tbaa_ptrarraybuf, data_owner, 0 ,
2751
- false ); // don't need to root the box if we had to make one since it's being stored in the array immediatly
2752
2753
}
2753
2754
}
2755
+ else {
2756
+ typed_store (emit_arrayptr (ary, args[1 ], ctx, isboxed), idx, rhs,
2757
+ ety, ctx, !isboxed ? tbaa_arraybuf : tbaa_ptrarraybuf, data_owner, 0 ,
2758
+ false ); // don't need to root the box if we had to make one since it's being stored in the array immediatly
2759
+ }
2754
2760
*ret = ary;
2755
2761
JL_GC_POP ();
2756
2762
return true ;
0 commit comments