diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 9a557bedbc56e..8d54ffc2a074c 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1573,8 +1573,7 @@ static bool emit_getfield_unknownidx(jl_cgval_t *ret, const jl_cgval_t &strct, V builder.CreateGEP(data_pointer(strct, ctx), idx))); if ((unsigned)stt->ninitialized != nfields) null_pointer_check(fld, ctx); - bool needsgcroot = true; // !strct.isimmutable; // jwn: probably want this as a llvm pass - *ret = mark_julia_type(fld, true, jl_any_type, ctx, needsgcroot); + *ret = mark_julia_type(fld, true, jl_any_type, ctx, true); return true; } else if (is_tupletype_homogeneous(stt->types)) { @@ -1586,9 +1585,9 @@ 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); - jl_cgval_t fieldval = mark_julia_slot(addr, jt); - fieldval.gcroot = strct.gcroot; - *ret = fieldval; + *ret = mark_julia_slot(addr, jt); + ret->gcroot = strct.gcroot; + ret->isimmutable = strct.isimmutable; return true; } *ret = typed_load(ptr, idx, jt, ctx, stt->mutabl ? tbaa_user : tbaa_immut); @@ -1653,13 +1652,12 @@ 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 = strct.isimmutable ? tbaa_immut : tbaa_user; + MDNode *tbaa = jt->mutabl ? tbaa_user : tbaa_immut; if (jl_field_isptr(jt, idx)) { Value *fldv = tbaa_decorate(tbaa, builder.CreateLoad(builder.CreateBitCast(addr, T_ppjlvalue))); if (idx >= (unsigned)jt->ninitialized) null_pointer_check(fldv, ctx); - bool needsgcroot = true; // !strct.isimmutable; // jwn: probably want this as a llvm pass - jl_cgval_t ret = mark_julia_type(fldv, true, jfty, ctx, needsgcroot); + jl_cgval_t ret = mark_julia_type(fldv, true, jfty, ctx, true); return ret; } else { @@ -1678,6 +1676,7 @@ static jl_cgval_t emit_getfield_knownidx(const jl_cgval_t &strct, unsigned idx, strct.V, 0, idx); assert(!jt->mutabl); jl_cgval_t fieldval = mark_julia_slot(addr, jfty); + fieldval.isimmutable = strct.isimmutable; fieldval.gcroot = strct.gcroot; return fieldval; } diff --git a/src/codegen.cpp b/src/codegen.cpp index faffd23bb802d..e06211ee5da30 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -661,6 +661,7 @@ static inline jl_cgval_t mark_julia_slot(Value *v, jl_value_t *typ) assert(v->getType() != T_pjlvalue); jl_cgval_t tagval(v, NULL, false, typ); tagval.ispointer = true; + tagval.isimmutable = true; return tagval; } @@ -782,7 +783,7 @@ static Value *alloc_local(jl_sym_t *s, jl_codectx_t *ctx) // CreateAlloca is OK here because alloc_local is only called during prologue setup Value *lv = builder.CreateAlloca(vtype, 0, jl_symbol_name(s)); vi.value = mark_julia_slot(lv, jt); - vi.value.isimmutable &= vi.isSA; // slot is not immutable if there are multiple assignments + vi.value.isimmutable = false; // slots are not immutable assert(vi.value.isboxed == false); return lv; } @@ -2977,10 +2978,10 @@ static jl_cgval_t emit_call_function_object(jl_lambda_info_t *li, const jl_cgval else if (et->isAggregateType()) { assert(at == PointerType::get(et, 0)); jl_cgval_t arg = i==0 ? theF : emit_expr(args[i], ctx); - if (arg.isimmutable && arg.ispointer) { + if (arg.ispointer) { // can lazy load on demand, no copy needed argvals[idx] = data_pointer(arg, ctx, at); - mark_gc_use(arg); // jwn must be after the jlcall + mark_gc_use(arg); // TODO: must be after the jlcall } else { Value *v = emit_unbox(et, arg, jt); @@ -3220,8 +3221,10 @@ static jl_cgval_t emit_var(jl_sym_t *sym, jl_codectx_t *ctx) } jl_varinfo_t &vi = ctx->vars[sym]; - if (!vi.isArgument && !vi.isAssigned) + if (!vi.isArgument && !vi.isAssigned) { undef_var_error_if_null(V_null, sym, ctx); + return jl_cgval_t(); + } if (vi.memloc) { Value *bp = vi.memloc; if (vi.isArgument || // arguments are always defined @@ -3236,7 +3239,7 @@ static jl_cgval_t emit_var(jl_sym_t *sym, jl_codectx_t *ctx) return v; } } - else if (vi.value.isboxed || vi.value.constant || !vi.value.ispointer || (vi.isSA && !vi.isVolatile)) { + else if (!vi.isVolatile || !vi.isAssigned) { return vi.value; } else { diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 165de5ae1dfae..cb68f82a3f6ad 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -529,12 +529,6 @@ static jl_cgval_t generic_unbox(jl_value_t *targ, jl_value_t *x, jl_codectx_t *c Value *vx; if (v.ispointer) { - // TODO: validate the size and type of the pointer contents - if (v.isimmutable && !v.constant) { // wrong type, but can lazy load this later as needed - v.typ = bt; - v.isboxed = false; - return v; - } vx = builder.CreateLoad(data_pointer(v, ctx, llvmt->getPointerTo())); } else {