Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Compiler/test/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1033,3 +1033,7 @@ end
const x57872 = "Hello"
f57872() = (Core.isdefinedglobal(@__MODULE__, Base.compilerbarrier(:const, :x57872)), x57872) # Extra globalref here to force world age bounds
@test f57872() == (true, "Hello")

@noinline f_mutateany(@nospecialize x) = x[] = 1
g_mutateany() = (y = Ref(0); f_mutateany(y); y[])
@test g_mutateany() === 1
2 changes: 1 addition & 1 deletion src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ static Value *emit_sizeof(jl_codectx_t &ctx, const jl_cgval_t &p)
return dyn_size;
}
}
*/

static Value *emit_datatype_mutabl(jl_codectx_t &ctx, Value *dt)
{
Expand All @@ -1493,7 +1494,6 @@ static Value *emit_datatype_mutabl(jl_codectx_t &ctx, Value *dt)
mutabl = ctx.builder.CreateLShr(mutabl, 1);
return ctx.builder.CreateTrunc(mutabl, getInt1Ty(ctx.builder.getContext()));
}
*/

static Value *emit_datatype_isprimitivetype(jl_codectx_t &ctx, Value *typ)
{
Expand Down
39 changes: 22 additions & 17 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ static MDNode *best_tbaa(jl_tbaacache_t &tbaa_cache, jl_value_t *jt) {
// note that this includes jl_isbits, although codegen should work regardless
static bool jl_is_concrete_immutable(jl_value_t* t)
{
return jl_is_immutable_datatype(t) && ((jl_datatype_t*)t)->isconcretetype;
return jl_may_be_immutable_datatype(t) && ((jl_datatype_t*)t)->isconcretetype;
}

static bool jl_is_pointerfree(jl_value_t* t)
Expand Down Expand Up @@ -7385,8 +7385,8 @@ static Function *gen_cfun_wrapper(
inputarg = mark_julia_type(ctx, val, false, jargty);
}
}
else if (static_at || (!jl_is_typevar(jargty) && !jl_is_immutable_datatype(jargty))) {
// must be a jl_value_t* (because it's mutable or contains gc roots)
else if (static_at || (!jl_is_typevar(jargty) && (!jl_is_datatype(jargty) || jl_is_abstracttype(jargty) || jl_is_mutable_datatype(jargty)))) {
// must be a jl_value_t* (because it is mutable or abstract)
inputarg = mark_julia_type(ctx, maybe_decay_untracked(ctx, val), true, jargty_proper);
}
else {
Expand All @@ -7400,31 +7400,36 @@ static Function *gen_cfun_wrapper(
emit_ptrgep(ctx, nestPtr, jl_array_nrows(*closure_types) * ctx.types().sizeof_ptr),
Align(sizeof(void*)));
BasicBlock *boxedBB = BasicBlock::Create(ctx.builder.getContext(), "isboxed", cw);
BasicBlock *loadBB = BasicBlock::Create(ctx.builder.getContext(), "need-load", cw);
BasicBlock *notanyBB = BasicBlock::Create(ctx.builder.getContext(), "not-any", cw);
BasicBlock *unboxedBB = BasicBlock::Create(ctx.builder.getContext(), "maybe-unboxed", cw);
BasicBlock *isanyBB = BasicBlock::Create(ctx.builder.getContext(), "any", cw);
BasicBlock *afterBB = BasicBlock::Create(ctx.builder.getContext(), "after", cw);
Value *isrtboxed = ctx.builder.CreateIsNull(val); // XXX: this is the wrong condition and should be inspecting runtime_dt instead
ctx.builder.CreateCondBr(isrtboxed, boxedBB, loadBB);
ctx.builder.SetInsertPoint(boxedBB);
Value *p1 = val;
p1 = track_pjlvalue(ctx, p1);
ctx.builder.CreateBr(afterBB);
ctx.builder.SetInsertPoint(loadBB);
Value *isrtany = ctx.builder.CreateICmpEQ(
literal_pointer_val(ctx, (jl_value_t*)jl_any_type), val);
ctx.builder.CreateCondBr(isrtany, isanyBB, unboxedBB);
track_pjlvalue(ctx,literal_pointer_val(ctx, (jl_value_t*)jl_any_type)), runtime_dt);
ctx.builder.CreateCondBr(isrtany, isanyBB, notanyBB);
ctx.builder.SetInsertPoint(isanyBB);
Value *p2 = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, val, Align(sizeof(void*)));
Value *p1 = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, val, Align(sizeof(void*)));
ctx.builder.CreateBr(afterBB);
isanyBB = ctx.builder.GetInsertBlock(); // could have changed
ctx.builder.SetInsertPoint(notanyBB);
jl_cgval_t runtime_dt_val = mark_julia_type(ctx, runtime_dt, true, jl_any_type);
Value *isrtboxed = // (!jl_is_datatype(runtime_dt) || !jl_is_concrete_datatype(runtime_dt) || jl_is_mutable_datatype(runtime_dt))
emit_guarded_test(ctx, emit_exactly_isa(ctx, runtime_dt_val, jl_datatype_type), true, [&] {
return ctx.builder.CreateOr(ctx.builder.CreateNot(emit_isconcrete(ctx, runtime_dt)), emit_datatype_mutabl(ctx, runtime_dt));
});
ctx.builder.CreateCondBr(isrtboxed, boxedBB, unboxedBB);
ctx.builder.SetInsertPoint(boxedBB);
Value *p2 = track_pjlvalue(ctx, val);
ctx.builder.CreateBr(afterBB);
boxedBB = ctx.builder.GetInsertBlock(); // could have changed
ctx.builder.SetInsertPoint(unboxedBB);
Value *p3 = emit_new_bits(ctx, runtime_dt, val);
unboxedBB = ctx.builder.GetInsertBlock(); // could have changed
ctx.builder.CreateBr(afterBB);
ctx.builder.SetInsertPoint(afterBB);
PHINode *p = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 3);
p->addIncoming(p1, boxedBB);
p->addIncoming(p2, isanyBB);
p->addIncoming(p1, isanyBB);
p->addIncoming(p2, boxedBB);
p->addIncoming(p3, unboxedBB);
inputarg = mark_julia_type(ctx, p, true, jargty_proper);
}
Expand Down Expand Up @@ -7980,7 +7985,7 @@ static jl_returninfo_t get_specsig_function(jl_codegen_params_t &params, Module
param.addAttribute(Attribute::ReadOnly);
ty = PointerType::get(M->getContext(), AddressSpace::Derived);
}
else if (isboxed && jl_is_immutable_datatype(jt)) {
else if (isboxed && jl_may_be_immutable_datatype(jt) && !jl_is_abstracttype(jt)) {
param.addAttribute(Attribute::ReadOnly);
}
else if (jl_is_primitivetype(jt) && ty->isIntegerTy()) {
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ static inline int jl_field_isconst(jl_datatype_t *st, int i) JL_NOTSAFEPOINT
#define jl_is_mutable(t) (((jl_datatype_t*)t)->name->mutabl)
#define jl_is_mutable_datatype(t) (jl_is_datatype(t) && (((jl_datatype_t*)t)->name->mutabl))
#define jl_is_immutable(t) (!((jl_datatype_t*)t)->name->mutabl)
#define jl_is_immutable_datatype(t) (jl_is_datatype(t) && (!((jl_datatype_t*)t)->name->mutabl))
#define jl_may_be_immutable_datatype(t) (jl_is_datatype(t) && (!((jl_datatype_t*)t)->name->mutabl))
#define jl_is_uniontype(v) jl_typetagis(v,jl_uniontype_tag<<4)
#define jl_is_typevar(v) jl_typetagis(v,jl_tvar_tag<<4)
#define jl_is_unionall(v) jl_typetagis(v,jl_unionall_tag<<4)
Expand Down