Skip to content

Commit 462ac49

Browse files
committed
Backport: Avoid generic call in most cases for getproperty (#50523)
1 parent fa5fbbb commit 462ac49

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/codegen.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,18 @@ static const auto jlgetnthfieldchecked_func = new JuliaFunction{
10551055
Attributes(C, {Attribute::NonNull}),
10561056
None); },
10571057
};
1058+
static const auto jlfieldindex_func = new JuliaFunction{
1059+
XSTR(jl_field_index),
1060+
[](LLVMContext &C) {
1061+
auto T_prjlvalue = JuliaType::get_prjlvalue_ty(C);
1062+
return FunctionType::get(getInt32Ty(C),
1063+
{T_prjlvalue, T_prjlvalue, getInt32Ty(C)}, false);
1064+
},
1065+
[](LLVMContext &C) { return AttributeList::get(C,
1066+
Attributes(C, {Attribute::NoUnwind, Attribute::ReadOnly, Attribute::WillReturn}),
1067+
AttributeSet(),
1068+
None); }, // This function can error if the third argument is 1 so don't do that.
1069+
};
10581070
static const auto jlfieldisdefinedchecked_func = new JuliaFunction{
10591071
XSTR(jl_field_isdefined_checked),
10601072
[](LLVMContext &C) {
@@ -3715,9 +3727,9 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
37153727
*ret = mark_julia_type(ctx, fld_val, true, jl_any_type);
37163728
return true;
37173729
}
3718-
} else if (fld.typ == (jl_value_t*)jl_symbol_type) {
3719-
if (jl_is_datatype(utt) && !jl_is_namedtuple_type(utt)) { // TODO: Look into this for NamedTuple
3720-
if (jl_struct_try_layout(utt) && (jl_datatype_nfields(utt) == 1)) {
3730+
} else if (fld.typ == (jl_value_t*)jl_symbol_type) { // Known type but unknown symbol
3731+
if (jl_is_datatype(utt) && (utt != jl_module_type) && jl_struct_try_layout(utt)) {
3732+
if ((jl_datatype_nfields(utt) == 1 && !jl_is_namedtuple_type(utt))) {
37213733
jl_svec_t *fn = jl_field_names(utt);
37223734
assert(jl_svec_len(fn) == 1);
37233735
Value *typ_sym = literal_pointer_val(ctx, jl_svecref(fn, 0));
@@ -3726,6 +3738,15 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
37263738
*ret = emit_getfield_knownidx(ctx, obj, 0, utt, order);
37273739
return true;
37283740
}
3741+
else {
3742+
Value *index = ctx.builder.CreateCall(prepare_call(jlfieldindex_func),
3743+
{emit_typeof_boxed(ctx, obj, false), boxed(ctx, fld), ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)});
3744+
Value *cond = ctx.builder.CreateICmpNE(index, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), -1));
3745+
emit_hasnofield_error_ifnot(ctx, cond, utt->name->name, fld);
3746+
Value *idx2 = ctx.builder.CreateAdd(ctx.builder.CreateIntCast(index, getSizeTy(ctx.builder.getContext()), false), ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1)); // getfield_unknown is 1 based
3747+
if (emit_getfield_unknownidx(ctx, ret, obj, idx2, utt, jl_false, order))
3748+
return true;
3749+
}
37293750
}
37303751
}
37313752
// TODO: generic getfield func with more efficient calling convention
@@ -8774,6 +8795,7 @@ static void init_jit_functions(void)
87748795
add_named_global("jl_adopt_thread", &jl_adopt_thread);
87758796
add_named_global(jlgetcfunctiontrampoline_func, &jl_get_cfunction_trampoline);
87768797
add_named_global(jlgetnthfieldchecked_func, &jl_get_nth_field_checked);
8798+
add_named_global(jlfieldindex_func, &jl_field_index);
87778799
add_named_global(diff_gc_total_bytes_func, &jl_gc_diff_total_bytes);
87788800
add_named_global(sync_gc_total_bytes_func, &jl_gc_sync_total_bytes);
87798801
add_named_global(jlarray_data_owner_func, &jl_array_data_owner);

0 commit comments

Comments
 (0)