@@ -1064,10 +1064,20 @@ static void raise_exception_unless(jl_codectx_t &ctx, Value *cond, Value *exc)
1064
1064
raise_exception (ctx, exc, passBB);
1065
1065
}
1066
1066
1067
- static void null_pointer_check (jl_codectx_t &ctx, Value *v)
1067
+ static Value * null_pointer_cmp (jl_codectx_t &ctx, Value *v)
1068
1068
{
1069
- raise_exception_unless (ctx,
1070
- ctx.builder .CreateICmpNE (v, Constant::getNullValue (v->getType ())),
1069
+ return ctx.builder .CreateICmpNE (v, Constant::getNullValue (v->getType ()));
1070
+ }
1071
+
1072
+ // If `nullcheck` is not NULL and a pointer NULL check is necessary
1073
+ // store the pointer to be checked in `*nullcheck` instead of checking it
1074
+ static void null_pointer_check (jl_codectx_t &ctx, Value *v, Value **nullcheck = nullptr )
1075
+ {
1076
+ if (nullcheck) {
1077
+ *nullcheck = v;
1078
+ return ;
1079
+ }
1080
+ raise_exception_unless (ctx, null_pointer_cmp (ctx, v),
1071
1081
literal_pointer_val (ctx, jl_undefref_exception));
1072
1082
}
1073
1083
@@ -1378,9 +1388,12 @@ Value *extract_first_ptr(jl_codectx_t &ctx, Value *V)
1378
1388
return ctx.builder .CreateExtractValue (V, path);
1379
1389
}
1380
1390
1391
+ // If `nullcheck` is not NULL and a pointer NULL check is necessary
1392
+ // store the pointer to be checked in `*nullcheck` instead of checking it
1381
1393
static jl_cgval_t typed_load (jl_codectx_t &ctx, Value *ptr, Value *idx_0based, jl_value_t *jltype,
1382
1394
MDNode *tbaa, MDNode *aliasscope,
1383
- bool maybe_null_if_boxed = true , unsigned alignment = 0 )
1395
+ bool maybe_null_if_boxed = true , unsigned alignment = 0 ,
1396
+ Value **nullcheck = nullptr )
1384
1397
{
1385
1398
bool isboxed;
1386
1399
Type *elty = julia_type_to_llvm (ctx, jltype, &isboxed);
@@ -1416,7 +1429,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1416
1429
if (maybe_null_if_boxed) {
1417
1430
Value *first_ptr = isboxed ? load : extract_first_ptr (ctx, load);
1418
1431
if (first_ptr)
1419
- null_pointer_check (ctx, first_ptr);
1432
+ null_pointer_check (ctx, first_ptr, nullcheck );
1420
1433
}
1421
1434
// }
1422
1435
if (jltype == (jl_value_t *)jl_bool_type) { // "freeze" undef memory to a valid value
@@ -1580,7 +1593,9 @@ static void emit_memcpy(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, const j
1580
1593
1581
1594
1582
1595
1583
- static jl_cgval_t emit_getfield_knownidx (jl_codectx_t &ctx, const jl_cgval_t &strct, unsigned idx, jl_datatype_t *jt);
1596
+ static jl_cgval_t emit_getfield_knownidx (jl_codectx_t &ctx, const jl_cgval_t &strct,
1597
+ unsigned idx, jl_datatype_t *jt,
1598
+ Value **nullcheck = nullptr );
1584
1599
1585
1600
static bool emit_getfield_unknownidx (jl_codectx_t &ctx,
1586
1601
jl_cgval_t *ret, jl_cgval_t strct,
@@ -1711,7 +1726,11 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
1711
1726
return false ;
1712
1727
}
1713
1728
1714
- static jl_cgval_t emit_getfield_knownidx (jl_codectx_t &ctx, const jl_cgval_t &strct, unsigned idx, jl_datatype_t *jt)
1729
+ // If `nullcheck` is not NULL and a pointer NULL check is necessary
1730
+ // store the pointer to be checked in `*nullcheck` instead of checking it
1731
+ static jl_cgval_t emit_getfield_knownidx (jl_codectx_t &ctx, const jl_cgval_t &strct,
1732
+ unsigned idx, jl_datatype_t *jt,
1733
+ Value **nullcheck)
1715
1734
{
1716
1735
jl_value_t *jfty = jl_field_type (jt, idx);
1717
1736
if (jfty == jl_bottom_type) {
@@ -1759,7 +1778,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
1759
1778
maybe_mark_load_dereferenceable (Load, maybe_null, jl_field_type (jt, idx));
1760
1779
Value *fldv = tbaa_decorate (tbaa, Load);
1761
1780
if (maybe_null)
1762
- null_pointer_check (ctx, fldv);
1781
+ null_pointer_check (ctx, fldv, nullcheck );
1763
1782
return mark_julia_type (ctx, fldv, true , jfty);
1764
1783
}
1765
1784
else if (jl_is_uniontype (jfty)) {
@@ -1796,7 +1815,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
1796
1815
return mark_julia_slot (addr, jfty, NULL , tbaa);
1797
1816
}
1798
1817
unsigned align = jl_field_align (jt, idx);
1799
- return typed_load (ctx, addr, NULL , jfty, tbaa, nullptr , maybe_null, align);
1818
+ return typed_load (ctx, addr, NULL , jfty, tbaa, nullptr , maybe_null, align, nullcheck );
1800
1819
}
1801
1820
else if (isa<UndefValue>(strct.V )) {
1802
1821
return jl_cgval_t ();
@@ -1858,7 +1877,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
1858
1877
if (maybe_null) {
1859
1878
Value *first_ptr = jl_field_isptr (jt, idx) ? fldv : extract_first_ptr (ctx, fldv);
1860
1879
if (first_ptr)
1861
- null_pointer_check (ctx, first_ptr);
1880
+ null_pointer_check (ctx, first_ptr, nullcheck );
1862
1881
}
1863
1882
return mark_julia_type (ctx, fldv, jl_field_isptr (jt, idx), jfty);
1864
1883
}
0 commit comments