diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 5b317eff7c0a7..74776fb484b3b 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -865,7 +865,7 @@ static Value *emit_nthptr_recast(Value *v, size_t n, MDNode *tbaa, Type* ptype) static Value *ghostValue(jl_value_t *ty); static Value *typed_load(Value *ptr, Value *idx_0based, jl_value_t *jltype, - jl_codectx_t *ctx) + jl_codectx_t *ctx, MDNode* tbaa) { Type *elty = julia_type_to_llvm(jltype); assert(elty != NULL); @@ -878,7 +878,7 @@ static Value *typed_load(Value *ptr, Value *idx_0based, jl_value_t *jltype, data = builder.CreateBitCast(ptr, PointerType::get(elty, 0)); else data = ptr; - Value *elt = tbaa_decorate(tbaa_user, builder.CreateLoad(builder.CreateGEP(data, idx_0based), false)); + Value *elt = tbaa_decorate(tbaa, builder.CreateLoad(builder.CreateGEP(data, idx_0based), false)); if (elty == jl_pvalue_llvmt) { null_pointer_check(elt, ctx); } @@ -890,7 +890,7 @@ static Value *typed_load(Value *ptr, Value *idx_0based, jl_value_t *jltype, static Value *emit_unbox(Type *to, Value *x, jl_value_t *jt); static void typed_store(Value *ptr, Value *idx_0based, Value *rhs, - jl_value_t *jltype, jl_codectx_t *ctx) + jl_value_t *jltype, jl_codectx_t *ctx, MDNode* tbaa) { Type *elty = julia_type_to_llvm(jltype); assert(elty != NULL); @@ -906,7 +906,7 @@ static void typed_store(Value *ptr, Value *idx_0based, Value *rhs, data = builder.CreateBitCast(ptr, PointerType::get(elty, 0)); else data = ptr; - tbaa_decorate(tbaa_user, builder.CreateStore(rhs, builder.CreateGEP(data, idx_0based))); + tbaa_decorate(tbaa, builder.CreateStore(rhs, builder.CreateGEP(data, idx_0based))); } // --- convert boolean value to julia --- diff --git a/src/codegen.cpp b/src/codegen.cpp index c869c3adbbcee..c7c08b8b766f7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -240,6 +240,7 @@ static Type *T_void; // type-based alias analysis nodes. Indentation of comments indicates hierarchy. static MDNode* tbaa_user; // User data static MDNode* tbaa_value; // Julia value +static MDNode* tbaa_immut; // Data inside a heap-allocated immutable static MDNode* tbaa_array; // Julia array static MDNode* tbaa_arrayptr; // The pointer inside a jl_array_t static MDNode* tbaa_arraysize; // A size in a jl_array_t @@ -1487,13 +1488,14 @@ static Value *emit_getfield(jl_value_t *expr, jl_sym_t *name, jl_codectx_t *ctx) ConstantInt::get(T_size, sty->fields[idx].offset + sizeof(void*))); JL_GC_POP(); + MDNode *tbaa = sty->mutabl ? tbaa_user : tbaa_immut; if (sty->fields[idx].isptr) { - Value *fldv = builder.CreateLoad(builder.CreateBitCast(addr,jl_ppvalue_llvmt)); + Value *fldv = tbaa_decorate(tbaa, builder.CreateLoad(builder.CreateBitCast(addr,jl_ppvalue_llvmt))); null_pointer_check(fldv, ctx); return fldv; } else { - return typed_load(addr, ConstantInt::get(T_size, 0), jfty, ctx); + return typed_load(addr, ConstantInt::get(T_size, 0), jfty, ctx, tbaa); } } else { @@ -1551,7 +1553,7 @@ static void emit_setfield(jl_datatype_t *sty, Value *strct, size_t idx, builder.CreateBitCast(addr, jl_ppvalue_llvmt)); } else { - typed_store(addr, ConstantInt::get(T_size, 0), rhs, jfty, ctx); + typed_store(addr, ConstantInt::get(T_size, 0), rhs, jfty, ctx, sty->mutabl ? tbaa_user : tbaa_immut); } } else { @@ -2064,7 +2066,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs, assert(((jl_datatype_t*)ety)->instance != NULL); return literal_pointer_val(((jl_datatype_t*)ety)->instance); } - return typed_load(emit_arrayptr(ary, args[1], ctx), idx, ety, ctx); + return typed_load(emit_arrayptr(ary, args[1], ctx), idx, ety, ctx, tbaa_user); } } } @@ -2097,7 +2099,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs, else { typed_store(emit_arrayptr(ary,args[1],ctx), idx, ety==(jl_value_t*)jl_any_type ? emit_expr(args[2],ctx) : emit_unboxed(args[2],ctx), - ety, ctx); + ety, ctx, tbaa_user); } JL_GC_POP(); return ary; @@ -2152,7 +2154,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs, idx = emit_bounds_check(idx, ConstantInt::get(T_size, nfields), ctx); Value *ptr = data_pointer(strct); JL_GC_POP(); - return typed_load(ptr, idx, jt, ctx); + return typed_load(ptr, idx, jt, ctx, stt->mutabl ? tbaa_user : tbaa_immut); } else { idx = builder.CreateSub(idx, ConstantInt::get(T_size, 1)); @@ -2179,7 +2181,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs, jl_value_t *jt = jl_t0(stt->types); idx = emit_bounds_check(idx, ConstantInt::get(T_size, nfields), ctx); Value *ptr = builder.CreateGEP(tempSpace, ConstantInt::get(T_size, 0)); - fld = typed_load(ptr, idx, jt, ctx); + fld = typed_load(ptr, idx, jt, ctx, stt->mutabl ? tbaa_user : tbaa_immut); builder.CreateCall(Intrinsic::getDeclaration(jl_Module,Intrinsic::stackrestore), stacksave); } @@ -4188,6 +4190,7 @@ static void init_julia_llvm_env(Module *m) MDNode* tbaa_root = mbuilder->createTBAARoot("jtbaa"); tbaa_user = tbaa_make_child("jtbaa_user",tbaa_root); tbaa_value = tbaa_make_child("jtbaa_value",tbaa_root); + tbaa_immut = tbaa_make_child("jtbaa_immut",tbaa_root); tbaa_array = tbaa_make_child("jtbaa_array",tbaa_value); tbaa_arrayptr = tbaa_make_child("jtbaa_arrayptr",tbaa_array); tbaa_arraysize = tbaa_make_child("jtbaa_arraysize",tbaa_array); diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index cf1a6165a4a2c..b86f92c4f6dcd 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -744,7 +744,7 @@ static Value *emit_pointerref(jl_value_t *e, jl_value_t *i, jl_codectx_t *ctx) thePtr, size, 1); return mark_julia_type(strct, ety); } - return typed_load(thePtr, im1, ety, ctx); + return typed_load(thePtr, im1, ety, ctx, tbaa_user); } static Value *emit_runtime_pointerset(jl_value_t *e, jl_value_t *x, jl_value_t *i, jl_codectx_t *ctx) @@ -803,7 +803,7 @@ static Value *emit_pointerset(jl_value_t *e, jl_value_t *x, jl_value_t *i, jl_co else val = emit_unboxed(x,ctx); } - typed_store(thePtr, im1, val, ety, ctx); + typed_store(thePtr, im1, val, ety, ctx, tbaa_user); } return mark_julia_type(thePtr, aty); }