Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid generic call in most cases for getproperty #50523

Merged
merged 9 commits into from
Jul 25, 2023
27 changes: 24 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,18 @@ static const auto jlgetnthfieldchecked_func = new JuliaFunction<TypeFnContextAnd
Attributes(C, {Attribute::NonNull}),
None); },
};
static const auto jlfieldindex_func = new JuliaFunction<>{
XSTR(jl_field_index),
[](LLVMContext &C) {
auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
return FunctionType::get(getInt32Ty(C),
{T_prjlvalue, T_prjlvalue, getInt32Ty(C)}, false);
},
[](LLVMContext &C) { return AttributeList::get(C,
Attributes(C, {Attribute::NoUnwind, Attribute::ReadOnly, Attribute::WillReturn}),
AttributeSet(),
None); }, // This function can error if the third argument is 1 so don't do that.
};
static const auto jlfieldisdefinedchecked_func = new JuliaFunction<TypeFnContextAndSizeT>{
XSTR(jl_field_isdefined_checked),
[](LLVMContext &C, Type *T_size) {
Expand Down Expand Up @@ -3829,8 +3841,8 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
}
}
else if (fld.typ == (jl_value_t*)jl_symbol_type) {
if (jl_is_datatype(utt) && !jl_is_namedtuple_type(utt)) { // TODO: Look into this for NamedTuple
if (jl_struct_try_layout(utt) && (jl_datatype_nfields(utt) == 1)) {
if (jl_is_datatype(utt) && (utt != jl_module_type) && jl_struct_try_layout(utt)) {
if ((jl_datatype_nfields(utt) == 1 && !jl_is_namedtuple_type(utt))) {
gbaraldi marked this conversation as resolved.
Show resolved Hide resolved
jl_svec_t *fn = jl_field_names(utt);
assert(jl_svec_len(fn) == 1);
Value *typ_sym = literal_pointer_val(ctx, jl_svecref(fn, 0));
Expand All @@ -3839,9 +3851,17 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
*ret = emit_getfield_knownidx(ctx, obj, 0, utt, order);
return true;
}
else {
Value *index = ctx.builder.CreateCall(prepare_call(jlfieldindex_func),
{emit_typeof(ctx, obj, false, false), boxed(ctx, fld), ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)});
Copy link
Member

@NHDaly NHDaly Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boxed(ctx, fld)

Does LLVM then unbox the fld value, before this actually reaches real code? This PR is meant to remove an allocation here right?

Can you also leave a comment explaining that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boxed checks if the object needs a box before being passed into julia, if it was an Int or something without a type tag. In this case fld is known to be a Symbol so it's a no op. The boxing that used to happen here is because we used the generic jlcall convention.
I can add a comment if you think it's useful though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think anything where the reason for the core isn't obvious or straightforward should have a comment. 👍 Thanks

Value *cond = ctx.builder.CreateICmpNE(index, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), -1));
emit_hasnofield_error_ifnot(ctx, cond, utt->name->name, fld);
Value *idx2 = ctx.builder.CreateAdd(ctx.builder.CreateIntCast(index, ctx.types().T_size, false), ConstantInt::get(ctx.types().T_size, 1));
if (emit_getfield_unknownidx(ctx, ret, obj, idx2, utt, jl_false, order))
return true;
}
}
}
// TODO: generic getfield func with more efficient calling convention
return false;
}
gbaraldi marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -9093,6 +9113,7 @@ static void init_jit_functions(void)
add_named_global("jl_adopt_thread", &jl_adopt_thread);
add_named_global(jlgetcfunctiontrampoline_func, &jl_get_cfunction_trampoline);
add_named_global(jlgetnthfieldchecked_func, &jl_get_nth_field_checked);
add_named_global(jlfieldindex_func, &jl_field_index);
add_named_global(diff_gc_total_bytes_func, &jl_gc_diff_total_bytes);
add_named_global(sync_gc_total_bytes_func, &jl_gc_sync_total_bytes);
add_named_global(jlarray_data_owner_func, &jl_array_data_owner);
Expand Down