@@ -1547,17 +1547,23 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1547
1547
Value *parent, // for the write barrier, NULL if no barrier needed
1548
1548
bool isboxed, AtomicOrdering Order, AtomicOrdering FailOrder, unsigned alignment,
1549
1549
bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield,
1550
- bool maybe_null_if_boxed, const std::string &fname)
1550
+ bool maybe_null_if_boxed, const jl_cgval_t *modifyop, const std::string &fname)
1551
1551
{
1552
1552
auto newval = [&](const jl_cgval_t &lhs) {
1553
- jl_cgval_t argv[3 ] = { cmp, lhs, rhs };
1554
- Value *callval = emit_jlcall (ctx, jlapplygeneric_func, nullptr , argv, 3 , JLCALL_F_CC);
1555
- argv[0 ] = mark_julia_type (ctx, callval, true , jl_any_type);
1556
- if (!jl_subtype (argv[0 ].typ , jltype)) {
1557
- emit_typecheck (ctx, argv[0 ], jltype, fname + " typed_store" );
1558
- argv[0 ] = update_julia_type (ctx, argv[0 ], jltype);
1559
- }
1560
- return argv[0 ];
1553
+ const jl_cgval_t argv[3 ] = { cmp, lhs, rhs };
1554
+ jl_cgval_t ret;
1555
+ if (modifyop) {
1556
+ ret = emit_invoke (ctx, *modifyop, argv, 3 , (jl_value_t *)jl_any_type);
1557
+ }
1558
+ else {
1559
+ Value *callval = emit_jlcall (ctx, jlapplygeneric_func, nullptr , argv, 3 , JLCALL_F_CC);
1560
+ ret = mark_julia_type (ctx, callval, true , jl_any_type);
1561
+ }
1562
+ if (!jl_subtype (ret.typ , jltype)) {
1563
+ emit_typecheck (ctx, ret, jltype, fname + " typed_store" );
1564
+ ret = update_julia_type (ctx, ret, jltype);
1565
+ }
1566
+ return ret;
1561
1567
};
1562
1568
assert (!needlock || parent != nullptr );
1563
1569
Type *elty = isboxed ? T_prjlvalue : julia_type_to_llvm (ctx, jltype);
@@ -1570,7 +1576,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1570
1576
else if (isreplacefield) {
1571
1577
Value *Success = emit_f_is (ctx, cmp, ghostValue (jltype));
1572
1578
Success = ctx.builder .CreateZExt (Success, T_int8);
1573
- jl_cgval_t argv[2 ] = {ghostValue (jltype), mark_julia_type (ctx, Success, false , jl_bool_type)};
1579
+ const jl_cgval_t argv[2 ] = {ghostValue (jltype), mark_julia_type (ctx, Success, false , jl_bool_type)};
1574
1580
jl_datatype_t *rettyp = jl_apply_cmpswap_type (jltype);
1575
1581
return emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
1576
1582
}
@@ -1579,7 +1585,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1579
1585
}
1580
1586
else { // modifyfield
1581
1587
jl_cgval_t oldval = ghostValue (jltype);
1582
- jl_cgval_t argv[2 ] = { oldval, newval (oldval) };
1588
+ const jl_cgval_t argv[2 ] = { oldval, newval (oldval) };
1583
1589
jl_datatype_t *rettyp = jl_apply_modify_type (jltype);
1584
1590
return emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
1585
1591
}
@@ -1862,7 +1868,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1862
1868
}
1863
1869
}
1864
1870
if (ismodifyfield) {
1865
- jl_cgval_t argv[2 ] = { oldval, rhs };
1871
+ const jl_cgval_t argv[2 ] = { oldval, rhs };
1866
1872
jl_datatype_t *rettyp = jl_apply_modify_type (jltype);
1867
1873
oldval = emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
1868
1874
}
@@ -1881,7 +1887,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
1881
1887
oldval = mark_julia_type (ctx, instr, isboxed, jltype);
1882
1888
if (isreplacefield) {
1883
1889
Success = ctx.builder .CreateZExt (Success, T_int8);
1884
- jl_cgval_t argv[2 ] = {oldval, mark_julia_type (ctx, Success, false , jl_bool_type)};
1890
+ const jl_cgval_t argv[2 ] = {oldval, mark_julia_type (ctx, Success, false , jl_bool_type)};
1885
1891
jl_datatype_t *rettyp = jl_apply_cmpswap_type (jltype);
1886
1892
oldval = emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
1887
1893
}
@@ -3269,7 +3275,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
3269
3275
jl_cgval_t rhs, jl_cgval_t cmp,
3270
3276
bool checked, bool wb, AtomicOrdering Order, AtomicOrdering FailOrder,
3271
3277
bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield,
3272
- const std::string &fname)
3278
+ const jl_cgval_t *modifyop, const std::string &fname)
3273
3279
{
3274
3280
if (!sty->name ->mutabl && checked) {
3275
3281
std::string msg = fname + " immutable struct of type "
@@ -3309,9 +3315,14 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
3309
3315
if (ismodifyfield) {
3310
3316
if (needlock)
3311
3317
emit_lockstate_value (ctx, strct, false );
3312
- jl_cgval_t argv[3 ] = { cmp, oldval, rhs };
3313
- Value *callval = emit_jlcall (ctx, jlapplygeneric_func, nullptr , argv, 3 , JLCALL_F_CC);
3314
- rhs = mark_julia_type (ctx, callval, true , jl_any_type);
3318
+ const jl_cgval_t argv[3 ] = { cmp, oldval, rhs };
3319
+ if (modifyop) {
3320
+ rhs = emit_invoke (ctx, *modifyop, argv, 3 , (jl_value_t *)jl_any_type);
3321
+ }
3322
+ else {
3323
+ Value *callval = emit_jlcall (ctx, jlapplygeneric_func, nullptr , argv, 3 , JLCALL_F_CC);
3324
+ rhs = mark_julia_type (ctx, callval, true , jl_any_type);
3325
+ }
3315
3326
if (!jl_subtype (rhs.typ , jfty)) {
3316
3327
emit_typecheck (ctx, rhs, jfty, fname);
3317
3328
rhs = update_julia_type (ctx, rhs, jfty);
@@ -3364,7 +3375,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
3364
3375
return typed_store (ctx, addr, NULL , rhs, cmp, jfty, strct.tbaa , nullptr ,
3365
3376
wb ? maybe_bitcast (ctx, data_pointer (ctx, strct), T_pjlvalue) : nullptr ,
3366
3377
isboxed, Order, FailOrder, align,
3367
- needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, fname);
3378
+ needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, modifyop, fname);
3368
3379
}
3369
3380
}
3370
3381
@@ -3543,7 +3554,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
3543
3554
else
3544
3555
need_wb = false ;
3545
3556
emit_typecheck (ctx, rhs, jl_svecref (sty->types , i), " new" );
3546
- emit_setfield (ctx, sty, strctinfo, i, rhs, jl_cgval_t (), false , need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false , true , false , false , false , " " );
3557
+ emit_setfield (ctx, sty, strctinfo, i, rhs, jl_cgval_t (), false , need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false , true , false , false , false , nullptr , " " );
3547
3558
}
3548
3559
return strctinfo;
3549
3560
}
0 commit comments