Skip to content

Commit

Permalink
Track TBAA metadata in jl_cgval_t
Browse files Browse the repository at this point in the history
So that field load can be marked with the correct TBAA.
  • Loading branch information
yuyichao committed May 6, 2016
1 parent 775dc82 commit 7d77343
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 102 deletions.
10 changes: 5 additions & 5 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ static Value *runtime_sym_lookup(PointerType *funcptype, const char *f_lib, cons

Value *llvm_type_rewrite(Value *v, Type *from_type, Type *target_type,
bool tojulia, /* only matters if byref is set (declares the direction of the byref attribute) */
bool byref, /* only applies to arguments, set false for return values -- effectively the same as jl_cgval_t.ispointer */
bool byref, /* only applies to arguments, set false for return values -- effectively the same as jl_cgval_t.ispointer() */
bool issigned, /* determines whether an integer value should be zero or sign extended */
jl_codectx_t *ctx)
{
Expand Down Expand Up @@ -316,7 +316,7 @@ static Value *julia_to_native(Type *to, bool toboxed, jl_value_t *jlto, const jl
if (addressOf)
to = to->getContainedType(0);
Value *slot = emit_static_alloca(to, ctx);
if (!jvinfo.ispointer) {
if (!jvinfo.ispointer()) {
builder.CreateStore(emit_unbox(to, jvinfo, ety), slot);
}
else {
Expand Down Expand Up @@ -856,7 +856,7 @@ static jl_cgval_t mark_or_box_ccall_result(Value *result, bool isboxed, jl_value
Value *runtime_bt = boxed(emit_expr(rt_expr, ctx), ctx);
int nb = sizeof(void*);
return mark_julia_type(
init_bits_value(emit_allocobj(nb), runtime_bt, result),
init_bits_value(emit_allocobj(nb), runtime_bt, result, tbaa_user),
true,
(jl_value_t*)jl_pointer_type, ctx);
}
Expand Down Expand Up @@ -1359,7 +1359,7 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
if (sret) {
jl_cgval_t sret_val = emit_new_struct(rt,1,NULL,ctx); // TODO: is it valid to be creating an incomplete type this way?
assert(sret_val.typ != NULL && "Type was not concrete");
if (!sret_val.ispointer) {
if (!sret_val.ispointer()) {
Value *mem = emit_static_alloca(lrt, ctx);
builder.CreateStore(sret_val.V, mem);
result = mem;
Expand Down Expand Up @@ -1544,7 +1544,7 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
assert(newst.typ != NULL && "Type was not concrete");
assert(newst.isboxed);
// copy the data from the return value to the new struct
builder.CreateAlignedStore(result, builder.CreateBitCast(newst.V, prt->getPointerTo()), 16); // julia gc is aligned 16
tbaa_decorate(newst.tbaa, builder.CreateAlignedStore(result, builder.CreateBitCast(newst.V, prt->getPointerTo()), 16)); // julia gc is aligned 16
return newst;
}
else if (jlrt != prt) {
Expand Down
74 changes: 37 additions & 37 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static Value *julia_gv(const char *cname, void *addr)
// first see if there already is a GlobalVariable for this address
it = jl_value_to_llvm.find(addr);
if (it != jl_value_to_llvm.end())
return builder.CreateLoad(prepare_global((llvm::GlobalVariable*)it->second.gv));
return tbaa_decorate(tbaa_const, builder.CreateLoad(prepare_global((llvm::GlobalVariable*)it->second.gv)));

std::stringstream gvname;
gvname << cname << globalUnique++;
Expand All @@ -189,7 +189,7 @@ static Value *julia_gv(const char *cname, void *addr)
NULL, gvname.str());
addComdat(gv);
*(void**)jl_emit_and_add_to_shadow(gv, addr) = addr;
return builder.CreateLoad(gv);
return tbaa_decorate(tbaa_const, builder.CreateLoad(gv));
}

static Value *julia_gv(const char *prefix, jl_sym_t *name, jl_module_t *mod, void *addr)
Expand Down Expand Up @@ -491,7 +491,7 @@ static Value *emit_typeof(Value *tt)
{
// given p, a jl_value_t*, compute its type tag
assert(tt->getType() == T_pjlvalue);
tt = builder.CreateLoad(emit_typeptr_addr(tt), false);
tt = tbaa_decorate(tbaa_tag, builder.CreateLoad(emit_typeptr_addr(tt), false));
tt = builder.CreateIntToPtr(builder.CreateAnd(
builder.CreatePtrToInt(tt, T_size),
ConstantInt::get(T_size,~(uintptr_t)15)),
Expand All @@ -517,22 +517,22 @@ static Value *emit_typeof_boxed(const jl_cgval_t &p, jl_codectx_t *ctx)

static Value *emit_datatype_types(Value *dt)
{
return builder.
return tbaa_decorate(tbaa_datatype, builder.
CreateLoad(builder.
CreateBitCast(builder.
CreateGEP(builder.CreateBitCast(dt, T_pint8),
ConstantInt::get(T_size, offsetof(jl_datatype_t, types))),
T_ppjlvalue));
T_ppjlvalue)));
}

static Value *emit_datatype_nfields(Value *dt)
{
Value *nf = builder.
Value *nf = tbaa_decorate(tbaa_datatype, builder.
CreateLoad(builder.
CreateBitCast(builder.
CreateGEP(builder.CreateBitCast(dt, T_pint8),
ConstantInt::get(T_size, offsetof(jl_datatype_t, nfields))),
T_pint32));
T_pint32)));
#ifdef _P64
nf = builder.CreateSExt(nf, T_int64);
#endif
Expand All @@ -541,28 +541,28 @@ static Value *emit_datatype_nfields(Value *dt)

static Value *emit_datatype_size(Value *dt)
{
Value *size = builder.
Value *size = tbaa_decorate(tbaa_datatype, builder.
CreateLoad(builder.
CreateBitCast(builder.
CreateGEP(builder.CreateBitCast(dt, T_pint8),
ConstantInt::get(T_size, offsetof(jl_datatype_t, size))),
T_pint32));
T_pint32)));
return size;
}

static Value *emit_datatype_mutabl(Value *dt)
{
Value *mutabl = builder.
Value *mutabl = tbaa_decorate(tbaa_datatype, builder.
CreateLoad(builder.CreateGEP(builder.CreateBitCast(dt, T_pint8),
ConstantInt::get(T_size, offsetof(jl_datatype_t, mutabl))));
ConstantInt::get(T_size, offsetof(jl_datatype_t, mutabl)))));
return builder.CreateTrunc(mutabl, T_int1);
}

static Value *emit_datatype_abstract(Value *dt)
{
Value *abstract = builder.
Value *abstract = tbaa_decorate(tbaa_datatype, builder.
CreateLoad(builder.CreateGEP(builder.CreateBitCast(dt, T_pint8),
ConstantInt::get(T_size, offsetof(jl_datatype_t, abstract))));
ConstantInt::get(T_size, offsetof(jl_datatype_t, abstract)))));
return builder.CreateTrunc(abstract, T_int1);
}

Expand Down Expand Up @@ -634,7 +634,7 @@ static void raise_exception_if(Value *cond, Value *exc, jl_codectx_t *ctx)

static void raise_exception_if(Value *cond, GlobalVariable *exc, jl_codectx_t *ctx)
{
raise_exception_if(cond, (Value*)builder.CreateLoad(exc, false), ctx);
raise_exception_if(cond, (Value*)tbaa_decorate(tbaa_const, builder.CreateLoad(exc, false)), ctx);
}

static void null_pointer_check(Value *v, jl_codectx_t *ctx)
Expand Down Expand Up @@ -737,7 +737,7 @@ static Value *emit_bounds_check(const jl_cgval_t &ainfo, jl_value_t *ty, Value *
if (ainfo.isghost) {
a = Constant::getNullValue(T_pint8);
}
else if (!ainfo.ispointer) {
else if (!ainfo.ispointer()) {
// CreateAlloca is OK here since we are on an error branch
Value *tempSpace = builder.CreateAlloca(a->getType());
builder.CreateStore(a, tempSpace);
Expand Down Expand Up @@ -963,10 +963,10 @@ static Value *data_pointer(const jl_cgval_t &x, jl_codectx_t *ctx, Type *astype
static bool emit_getfield_unknownidx(jl_cgval_t *ret, const jl_cgval_t &strct, Value *idx, jl_datatype_t *stt, jl_codectx_t *ctx)
{
size_t nfields = jl_datatype_nfields(stt);
if (strct.ispointer) { // boxed or stack
if (strct.ispointer()) { // boxed or stack
if (is_datatype_all_pointers(stt)) {
idx = emit_bounds_check(strct, (jl_value_t*)stt, idx, ConstantInt::get(T_size, nfields), ctx);
Value *fld = tbaa_decorate(tbaa_user, builder.CreateLoad(
Value *fld = tbaa_decorate(strct.tbaa, builder.CreateLoad(
builder.CreateGEP(data_pointer(strct, ctx), idx)));
if ((unsigned)stt->ninitialized != nfields)
null_pointer_check(fld, ctx);
Expand All @@ -982,12 +982,12 @@ static bool emit_getfield_unknownidx(jl_cgval_t *ret, const jl_cgval_t &strct, V
// just compute the pointer and let user load it when necessary
Type *fty = julia_type_to_llvm(jt);
Value *addr = builder.CreateGEP(builder.CreatePointerCast(ptr, PointerType::get(fty,0)), idx);
*ret = mark_julia_slot(addr, jt);
*ret = mark_julia_slot(addr, jt, strct.tbaa);
ret->gcroot = strct.gcroot;
ret->isimmutable = strct.isimmutable;
return true;
}
*ret = typed_load(ptr, idx, jt, ctx, stt->mutabl ? tbaa_user : tbaa_immut);
*ret = typed_load(ptr, idx, jt, ctx, strct.tbaa);
return true;
}
else if (strct.isboxed) {
Expand Down Expand Up @@ -1045,7 +1045,7 @@ static jl_cgval_t emit_getfield_knownidx(const jl_cgval_t &strct, unsigned idx,
Value *addr =
builder.CreateGEP(builder.CreateBitCast(boxed(strct, ctx), T_pint8),
ConstantInt::get(T_size, jl_field_offset(jt,idx)));
MDNode *tbaa = jt->mutabl ? tbaa_user : tbaa_immut;
MDNode *tbaa = strct.tbaa;
if (jl_field_isptr(jt, idx)) {
Value *fldv = tbaa_decorate(tbaa, builder.CreateLoad(builder.CreateBitCast(addr, T_ppjlvalue)));
if (idx >= (unsigned)jt->ninitialized)
Expand All @@ -1060,7 +1060,7 @@ static jl_cgval_t emit_getfield_knownidx(const jl_cgval_t &strct, unsigned idx,
return typed_load(addr, ConstantInt::get(T_size, 0), jfty, ctx, tbaa, align);
}
}
else if (strct.ispointer) { // something stack allocated
else if (strct.ispointer()) { // something stack allocated
Value *addr;
if (is_vecelement_type((jl_value_t*)jt))
// VecElement types are unwrapped in LLVM.
Expand All @@ -1070,7 +1070,7 @@ static jl_cgval_t emit_getfield_knownidx(const jl_cgval_t &strct, unsigned idx,
LLVM37_param(julia_type_to_llvm(strct.typ))
strct.V, 0, idx);
assert(!jt->mutabl);
jl_cgval_t fieldval = mark_julia_slot(addr, jfty);
jl_cgval_t fieldval = mark_julia_slot(addr, jfty, strct.tbaa);
fieldval.isimmutable = strct.isimmutable;
fieldval.gcroot = strct.gcroot;
return fieldval;
Expand Down Expand Up @@ -1305,10 +1305,10 @@ static Value *emit_array_nd_index(const jl_cgval_t &ainfo, jl_value_t *ex, size_
// --- boxing ---

static Value *emit_allocobj(size_t static_size);
static Value *init_bits_value(Value *newv, Value *jt, Value *v)
static Value *init_bits_value(Value *newv, Value *jt, Value *v, MDNode *tbaa)
{
builder.CreateStore(jt, emit_typeptr_addr(newv));
builder.CreateAlignedStore(v, builder.CreateBitCast(newv, PointerType::get(v->getType(),0)), sizeof(void*)); // min alignment in julia's gc is pointer-aligned
tbaa_decorate(tbaa_tag, builder.CreateStore(jt, emit_typeptr_addr(newv)));
tbaa_decorate(tbaa, builder.CreateAlignedStore(v, builder.CreateBitCast(newv, PointerType::get(v->getType(),0)), sizeof(void*))); // min alignment in julia's gc is pointer-aligned
return newv;
}

Expand Down Expand Up @@ -1411,8 +1411,8 @@ static Value *boxed(const jl_cgval_t &vinfo, jl_codectx_t *ctx, bool gcrooted)
Type *t = julia_type_to_llvm(vinfo.typ);
assert(!type_is_ghost(t)); // should have been handled by isghost above!

if (vinfo.ispointer)
v = build_load( builder.CreatePointerCast(v, t->getPointerTo()), vinfo.typ );
if (vinfo.ispointer())
v = tbaa_decorate(vinfo.tbaa, build_load(builder.CreatePointerCast(v, t->getPointerTo()), vinfo.typ));

if (t == T_int1)
return julia_bool(v);
Expand Down Expand Up @@ -1468,7 +1468,7 @@ static Value *boxed(const jl_cgval_t &vinfo, jl_codectx_t *ctx, bool gcrooted)
return literal_pointer_val(jb->instance);
}
else {
box = init_bits_value(emit_allocobj(jl_datatype_size(jt)), literal_pointer_val(jt), v);
box = init_bits_value(emit_allocobj(jl_datatype_size(jt)), literal_pointer_val(jt), v, jb->mutabl ? tbaa_user : tbaa_immut);
}

if (gcrooted) {
Expand Down Expand Up @@ -1531,7 +1531,7 @@ static Value *emit_allocobj(size_t static_size)
static void emit_write_barrier(jl_codectx_t *ctx, Value *parent, Value *ptr)
{
Value *parenttag = builder.CreateBitCast(emit_typeptr_addr(parent), T_psize);
Value *parent_type = builder.CreateLoad(parenttag);
Value *parent_type = tbaa_decorate(tbaa_tag, builder.CreateLoad(parenttag));
Value *parent_mark_bits = builder.CreateAnd(parent_type, 1);

// the branch hint does not seem to make it to the generated code
Expand All @@ -1544,7 +1544,7 @@ static void emit_write_barrier(jl_codectx_t *ctx, Value *parent, Value *ptr)
builder.CreateCondBr(parent_marked, barrier_may_trigger, cont);

builder.SetInsertPoint(barrier_may_trigger);
Value *ptr_mark_bit = builder.CreateAnd(builder.CreateLoad(builder.CreateBitCast(emit_typeptr_addr(ptr), T_psize)), 1);
Value *ptr_mark_bit = builder.CreateAnd(tbaa_decorate(tbaa_tag, builder.CreateLoad(builder.CreateBitCast(emit_typeptr_addr(ptr), T_psize))), 1);
Value *ptr_not_marked = builder.CreateICmpEQ(ptr_mark_bit, ConstantInt::get(T_size, 0));
builder.CreateCondBr(ptr_not_marked, barrier_trigger, cont);
builder.SetInsertPoint(barrier_trigger);
Expand Down Expand Up @@ -1572,21 +1572,21 @@ static void emit_setfield(jl_datatype_t *sty, const jl_cgval_t &strct, size_t id
const jl_cgval_t &rhs, jl_codectx_t *ctx, bool checked, bool wb)
{
if (sty->mutabl || !checked) {
assert(strct.ispointer);
assert(strct.ispointer());
Value *addr = builder.CreateGEP(data_pointer(strct, ctx, T_pint8),
ConstantInt::get(T_size, jl_field_offset(sty, idx0)));
jl_value_t *jfty = jl_svecref(sty->types, idx0);
if (jl_field_isptr(sty, idx0)) {
Value *r = boxed(rhs, ctx, false); // don't need a temporary gcroot since it'll be rooted by strct (but should ensure strct is rooted via mark_gc_use)
builder.CreateStore(r, builder.CreateBitCast(addr, T_ppjlvalue));
tbaa_decorate(strct.tbaa, builder.CreateStore(r, builder.CreateBitCast(addr, T_ppjlvalue)));
if (wb && strct.isboxed) emit_checked_write_barrier(ctx, boxed(strct, ctx), r);
mark_gc_use(strct);
}
else {
int align = jl_field_offset(sty, idx0);
align |= 16;
align &= -align;
typed_store(addr, ConstantInt::get(T_size, 0), rhs, jfty, ctx, sty->mutabl ? tbaa_user : tbaa_immut, data_pointer(strct, ctx, T_pjlvalue), align);
typed_store(addr, ConstantInt::get(T_size, 0), rhs, jfty, ctx, strct.tbaa, data_pointer(strct, ctx, T_pjlvalue), align);
}
}
else {
Expand Down Expand Up @@ -1652,8 +1652,8 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
}
Value *strct = emit_allocobj(sty->size);
jl_cgval_t strctinfo = mark_julia_type(strct, true, ty, ctx);
builder.CreateStore(literal_pointer_val((jl_value_t*)ty),
emit_typeptr_addr(strct));
tbaa_decorate(tbaa_tag, builder.CreateStore(literal_pointer_val((jl_value_t*)ty),
emit_typeptr_addr(strct)));
if (f1) {
jl_cgval_t f1info = mark_julia_type(f1, true, jl_any_type, ctx);
if (!jl_subtype(expr_type(args[1],ctx), jl_field_type(sty,0), 0))
Expand All @@ -1662,12 +1662,12 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
}
for(size_t i=j; i < nf; i++) {
if (jl_field_isptr(sty, i)) {
builder.CreateStore(
tbaa_decorate(strctinfo.tbaa, builder.CreateStore(
V_null,
builder.CreatePointerCast(
builder.CreateGEP(builder.CreateBitCast(strct, T_pint8),
ConstantInt::get(T_size, jl_field_offset(sty,i))),
T_ppjlvalue));
T_ppjlvalue)));
}
}
bool need_wb = false;
Expand Down
Loading

0 comments on commit 7d77343

Please sign in to comment.