Skip to content

Commit 5579c73

Browse files
committed
Refactor TBAA hierarchy creating both immutable and mutable union selectors.
1 parent bb28ea8 commit 5579c73

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

Compiler/test/codegen.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,3 +1047,22 @@ f57872() = (Core.isdefinedglobal(@__MODULE__, Base.compilerbarrier(:const, :x578
10471047
@noinline f_mutateany(@nospecialize x) = x[] = 1
10481048
g_mutateany() = (y = Ref(0); f_mutateany(y); y[])
10491049
@test g_mutateany() === 1
1050+
1051+
# 58470 tbaa for unionselbyte for mut and immut
1052+
1053+
mutable struct Wrapper58470
1054+
x::Union{Nothing,Int}
1055+
end
1056+
1057+
function findsomething58470(dict, inds)
1058+
default = Wrapper58470(nothing)
1059+
for i in inds
1060+
x = get(dict, i, default).x
1061+
if !isnothing(x)
1062+
return x
1063+
end
1064+
end
1065+
return nothing
1066+
end
1067+
1068+
@test occursin("tindex_ptr", get_llvm(findsomething58470, Tuple{Dict{Int64, Wrapper58470}, Vector{Int}}))

src/cgutils.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,7 +3131,8 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
31313131
bool isptr = (union_max == 0);
31323132
assert(!isptr && fsz < jl_field_size(jt, idx)); (void)isptr;
31333133
Value *ptindex = emit_ptrgep(ctx, addr, fsz1);
3134-
return emit_unionload(ctx, addr, ptindex, jfty, fsz, al, tbaa, false, union_max, strct.tbaa);
3134+
auto tindex_tbaa = jl_is_mutable(strct.typ) ? ctx.tbaa().tbaa_mutable_unionselbyte : ctx.tbaa().tbaa_immut_unionselbyte;
3135+
return emit_unionload(ctx, addr, ptindex, jfty, fsz, al, tbaa, false, union_max, tindex_tbaa);
31353136
}
31363137
else if (jfty == (jl_value_t*)jl_bool_type) {
31373138
unsigned align = jl_field_align(jt, idx);
@@ -3166,7 +3167,8 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
31663167
assert(!isptr && fsz < jl_field_size(jt, idx)); (void)isptr;
31673168
size_t fsz1 = jl_field_size(jt, idx) - 1;
31683169
Value *ptindex = emit_ptrgep(ctx, staddr, byte_offset + fsz1);
3169-
auto val = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, tbaa, !jl_field_isconst(jt, idx), union_max, strct.tbaa);
3170+
auto tindex_tbaa = jl_is_mutable(strct.typ) ? ctx.tbaa().tbaa_mutable_unionselbyte : ctx.tbaa().tbaa_immut_unionselbyte;
3171+
auto val = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, tbaa, !jl_field_isconst(jt, idx), union_max, tindex_tbaa);
31703172
if (val.V && val.V != addr) {
31713173
setNameWithField(ctx.emission_context, val.V, get_objname, jt, idx, Twine());
31723174
}
@@ -4141,7 +4143,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
41414143
size_t fsz1 = jl_field_size(sty, idx0) - 1;
41424144
Value *ptindex = emit_ptrgep(ctx, addr, fsz1);
41434145
setNameWithField(ctx.emission_context, ptindex, get_objname, sty, idx0, Twine(".tindex_ptr"));
4144-
return union_store(ctx, addr, ptindex, rhs, cmp, jfty, tbaa, ctx.tbaa().tbaa_unionselbyte,
4146+
return union_store(ctx, addr, ptindex, rhs, cmp, jfty, tbaa, ctx.tbaa().tbaa_mutable_unionselbyte,
41454147
Order, FailOrder,
41464148
needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, issetfieldonce,
41474149
modifyop, fname);
@@ -4325,7 +4327,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
43254327
}
43264328
else {
43274329
Value *ptindex = emit_ptrgep(ctx, strct, offs + fsz1);
4328-
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_unionselbyte);
4330+
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_immut_unionselbyte);
43294331
ai.decorateInst(ctx.builder.CreateAlignedStore(tindex, ptindex, Align(1)));
43304332
if (!rhs_union.isghost)
43314333
emit_unionmove(ctx, dest, ctx.tbaa().tbaa_stack, fval_info, nullptr);
@@ -4409,7 +4411,8 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
44094411
undef_derived_strct(ctx, strct, sty, strctinfo.tbaa);
44104412
for (size_t i = nargs; i < nf; i++) {
44114413
if (!jl_field_isptr(sty, i) && jl_is_uniontype(jl_field_type(sty, i))) {
4412-
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_unionselbyte);
4414+
auto tindex_tbaa = jl_is_mutable(sty) ? ctx.tbaa().tbaa_mutable_unionselbyte : ctx.tbaa().tbaa_immut_unionselbyte;
4415+
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tindex_tbaa);
44134416
ai.decorateInst(ctx.builder.CreateAlignedStore(
44144417
ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0),
44154418
emit_ptrgep(ctx, strct, jl_field_offset(sty, i) + jl_field_size(sty, i) - 1),

src/codegen.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,12 @@ struct jl_tbaacache_t {
331331
// LLVM should have enough info for alias analysis of non-gcframe stack slot
332332
// this is mainly a place holder for `jl_cgval_t::tbaa`
333333
MDNode *tbaa_stack; // stack slot
334-
MDNode *tbaa_unionselbyte; // a selector byte in isbits Union struct fields
334+
MDNode *tbaa_immut_unionselbyte; // a selector byte in isbits Union struct fields
335335
MDNode *tbaa_data; // Any user data that `pointerset/ref` are allowed to alias
336336
MDNode *tbaa_binding; // jl_binding_t::value
337337
MDNode *tbaa_value; // jl_value_t, that is not jl_array_t or jl_genericmemory_t
338338
MDNode *tbaa_mutab; // mutable type
339+
MDNode *tbaa_mutable_unionselbyte; // a selector byte in mutable isbits Union struct fields
339340
MDNode *tbaa_datatype; // datatype
340341
MDNode *tbaa_immut; // immutable type
341342
MDNode *tbaa_ptrarraybuf; // Data in an array of boxed values
@@ -351,8 +352,8 @@ struct jl_tbaacache_t {
351352
bool initialized;
352353

353354
jl_tbaacache_t(): tbaa_root(nullptr), tbaa_gcframe(nullptr), tbaa_stack(nullptr),
354-
tbaa_unionselbyte(nullptr), tbaa_data(nullptr), tbaa_binding(nullptr),
355-
tbaa_value(nullptr), tbaa_mutab(nullptr), tbaa_datatype(nullptr),
355+
tbaa_immut_unionselbyte(nullptr), tbaa_data(nullptr), tbaa_binding(nullptr),
356+
tbaa_value(nullptr), tbaa_mutab(nullptr),tbaa_mutable_unionselbyte(nullptr), tbaa_datatype(nullptr),
356357
tbaa_immut(nullptr), tbaa_ptrarraybuf(nullptr), tbaa_arraybuf(nullptr),
357358
tbaa_array(nullptr), tbaa_arrayptr(nullptr), tbaa_arraysize(nullptr),
358359
tbaa_arrayselbyte(nullptr), tbaa_memoryptr(nullptr), tbaa_memorylen(nullptr), tbaa_memoryown(nullptr),
@@ -376,7 +377,6 @@ struct jl_tbaacache_t {
376377
tbaa_gcframe = tbaa_make_child(mbuilder, "jtbaa_gcframe").first;
377378
MDNode *tbaa_stack_scalar;
378379
std::tie(tbaa_stack, tbaa_stack_scalar) = tbaa_make_child(mbuilder, "jtbaa_stack");
379-
tbaa_unionselbyte = tbaa_make_child(mbuilder, "jtbaa_unionselbyte", tbaa_stack_scalar).first;
380380
MDNode *tbaa_data_scalar;
381381
std::tie(tbaa_data, tbaa_data_scalar) = tbaa_make_child(mbuilder, "jtbaa_data");
382382
tbaa_binding = tbaa_make_child(mbuilder, "jtbaa_binding", tbaa_data_scalar).first;
@@ -386,8 +386,11 @@ struct jl_tbaacache_t {
386386
MDNode *tbaa_mutab_scalar;
387387
std::tie(tbaa_mutab, tbaa_mutab_scalar) =
388388
tbaa_make_child(mbuilder, "jtbaa_mutab", tbaa_value_scalar);
389+
MDNode *tbaa_immut_scalar;
389390
tbaa_datatype = tbaa_make_child(mbuilder, "jtbaa_datatype", tbaa_mutab_scalar).first;
390-
tbaa_immut = tbaa_make_child(mbuilder, "jtbaa_immut", tbaa_value_scalar).first;
391+
tbaa_mutable_unionselbyte = tbaa_make_child(mbuilder, "jtbaa_mut_unionselbyte", tbaa_mutab_scalar).first;
392+
std::tie(tbaa_immut, tbaa_immut_scalar) = tbaa_make_child(mbuilder, "jtbaa_immut", tbaa_value_scalar);
393+
tbaa_immut_unionselbyte = tbaa_make_child(mbuilder, "jtbaa_immut_unionselbyte", tbaa_immut_scalar).first;
391394
tbaa_arraybuf = tbaa_make_child(mbuilder, "jtbaa_arraybuf", tbaa_data_scalar).first;
392395
tbaa_ptrarraybuf = tbaa_make_child(mbuilder, "jtbaa_ptrarraybuf", tbaa_data_scalar).first;
393396
MDNode *tbaa_array_scalar;

0 commit comments

Comments
 (0)