Skip to content

Optimize isassigned and inline jl_array_isassigned #20890

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

Merged
merged 1 commit into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ elsize{T}(a::Array{T}) = isbits(T) ? sizeof(T) : sizeof(Ptr)
sizeof(a::Array) = elsize(a) * length(a)

function isassigned(a::Array, i::Int...)
ii = sub2ind(size(a), i...)
1 <= ii <= length(a) || return false
ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii-1) == 1
@_inline_meta
ii = (sub2ind(size(a), i...) % UInt) - 1
ii < length(a) % UInt || return false
ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
end

## copy ##
Expand Down
29 changes: 29 additions & 0 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,35 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
}
JL_GC_POP();
}
if ((fptr == (void(*)(void))&jl_array_isassigned ||
((f_lib==NULL || (intptr_t)f_lib==2)
&& f_name && !strcmp(f_name, "jl_array_isassigned"))) &&
expr_type(args[6], ctx) == (jl_value_t*)jl_ulong_type) {
assert(nargt == 2);
jl_value_t *aryex = args[4];
jl_value_t *idxex = args[6];
jl_value_t *aryty = expr_type(aryex, ctx);
if (jl_is_array_type(aryty)) {
jl_value_t *ety = jl_tparam0(aryty);
if (jl_isbits(ety)) {
emit_expr(aryex, ctx);
emit_expr(idxex, ctx);
JL_GC_POP();
return mark_or_box_ccall_result(ConstantInt::get(T_int32, 1),
false, rt, unionall, static_rt, ctx);
}
else if (!jl_has_free_typevars(ety)) { // TODO: jn/foreigncall branch has a better predicate
Copy link
Contributor

Choose a reason for hiding this comment

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

didn't that branch get merged already?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is copied from the comment in codegen.cpp for arrayref and arrayset.

Copy link
Contributor

Choose a reason for hiding this comment

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

is it a stale comment there too then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No idea and not related to this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

you're copy pasting code that includes the comment, so yes it is related

Copy link
Contributor

Choose a reason for hiding this comment

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

bump, what is the better predicate?

jl_cgval_t aryv = emit_expr(aryex, ctx);
Value *idx = emit_unbox(T_size, emit_expr(idxex, ctx), (jl_value_t*)jl_ulong_type);
Value *arrayptr = emit_bitcast(emit_arrayptr(aryv, aryex, ctx), T_ppjlvalue);
Value *slot_addr = builder.CreateGEP(arrayptr, idx);
Value *load = tbaa_decorate(tbaa_arraybuf, builder.CreateLoad(slot_addr));
Value *res = builder.CreateZExt(builder.CreateICmpNE(load, V_null), T_int32);
JL_GC_POP();
return mark_or_box_ccall_result(res, retboxed, rt, unionall, static_rt, ctx);
}
}
}

// emit arguments
jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * (nargs - 3) / 2);
Expand Down
2 changes: 2 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1085,12 +1085,14 @@ JL_DLLEXPORT int jl_get_size(jl_value_t *val, size_t *pnt);
#define jl_unbox_long(x) jl_unbox_int64(x)
#define jl_is_long(x) jl_is_int64(x)
#define jl_long_type jl_int64_type
#define jl_ulong_type jl_uint64_type
#else
#define jl_box_long(x) jl_box_int32(x)
#define jl_box_ulong(x) jl_box_uint32(x)
#define jl_unbox_long(x) jl_unbox_int32(x)
#define jl_is_long(x) jl_is_int32(x)
#define jl_long_type jl_int32_type
#define jl_ulong_type jl_uint32_type
#endif

// Each tuple can exist in one of 4 Vararg states:
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ JL_DLLEXPORT jl_value_t *jl_arraylen(jl_value_t *a);
int jl_array_store_unboxed(jl_value_t *el_type);
int jl_array_isdefined(jl_value_t **args, int nargs);
JL_DLLEXPORT jl_value_t *(jl_array_data_owner)(jl_array_t *a);
JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i);

// -- synchronization utilities -- //

Expand Down