@@ -1547,17 +1547,23 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
15471547 Value *parent, // for the write barrier, NULL if no barrier needed
15481548 bool isboxed, AtomicOrdering Order, AtomicOrdering FailOrder, unsigned alignment,
15491549 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)
15511551{
15521552 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;
15611567 };
15621568 assert (!needlock || parent != nullptr );
15631569 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,
15701576 else if (isreplacefield) {
15711577 Value *Success = emit_f_is (ctx, cmp, ghostValue (jltype));
15721578 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)};
15741580 jl_datatype_t *rettyp = jl_apply_cmpswap_type (jltype);
15751581 return emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
15761582 }
@@ -1579,7 +1585,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
15791585 }
15801586 else { // modifyfield
15811587 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) };
15831589 jl_datatype_t *rettyp = jl_apply_modify_type (jltype);
15841590 return emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
15851591 }
@@ -1862,7 +1868,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
18621868 }
18631869 }
18641870 if (ismodifyfield) {
1865- jl_cgval_t argv[2 ] = { oldval, rhs };
1871+ const jl_cgval_t argv[2 ] = { oldval, rhs };
18661872 jl_datatype_t *rettyp = jl_apply_modify_type (jltype);
18671873 oldval = emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
18681874 }
@@ -1881,7 +1887,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
18811887 oldval = mark_julia_type (ctx, instr, isboxed, jltype);
18821888 if (isreplacefield) {
18831889 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)};
18851891 jl_datatype_t *rettyp = jl_apply_cmpswap_type (jltype);
18861892 oldval = emit_new_struct (ctx, (jl_value_t *)rettyp, 2 , argv);
18871893 }
@@ -3269,7 +3275,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
32693275 jl_cgval_t rhs, jl_cgval_t cmp,
32703276 bool checked, bool wb, AtomicOrdering Order, AtomicOrdering FailOrder,
32713277 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)
32733279{
32743280 if (!sty->name ->mutabl && checked) {
32753281 std::string msg = fname + " immutable struct of type "
@@ -3309,9 +3315,14 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
33093315 if (ismodifyfield) {
33103316 if (needlock)
33113317 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+ }
33153326 if (!jl_subtype (rhs.typ , jfty)) {
33163327 emit_typecheck (ctx, rhs, jfty, fname);
33173328 rhs = update_julia_type (ctx, rhs, jfty);
@@ -3364,7 +3375,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
33643375 return typed_store (ctx, addr, NULL , rhs, cmp, jfty, strct.tbaa , nullptr ,
33653376 wb ? maybe_bitcast (ctx, data_pointer (ctx, strct), T_pjlvalue) : nullptr ,
33663377 isboxed, Order, FailOrder, align,
3367- needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, fname);
3378+ needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, modifyop, fname);
33683379 }
33693380}
33703381
@@ -3543,7 +3554,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
35433554 else
35443555 need_wb = false ;
35453556 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 , " " );
35473558 }
35483559 return strctinfo;
35493560 }
0 commit comments