Skip to content

Commit 19e1d93

Browse files
committed
expand memoryrefnew capabilities
1 parent a812f03 commit 19e1d93

File tree

6 files changed

+44
-18
lines changed

6 files changed

+44
-18
lines changed

Compiler/src/optimize.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,9 @@ function iscall_with_boundscheck(@nospecialize(stmt), sv::PostOptAnalysisState)
720720
f === nothing && return false
721721
if f === getfield
722722
nargs = 4
723-
elseif f === memoryrefnew || f === memoryrefget || f === memoryref_isassigned
723+
elseif f === memoryrefnew
724+
nargs= 3
725+
elseif f === memoryrefget || f === memoryref_isassigned
724726
nargs = 4
725727
elseif f === memoryrefset!
726728
nargs = 5

Compiler/src/tfuncs.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,7 +2107,7 @@ end
21072107
add_tfunc(memoryrefoffset, 1, 1, memoryrefoffset_tfunc, 5)
21082108

21092109
@nospecs function memoryref_builtin_common_errorcheck(mem, order, boundscheck)
2110-
hasintersect(widenconst(mem), GenericMemoryRef) || return false
2110+
hasintersect(widenconst(mem), Union{GenericMemory, GenericMemoryRef}) || return false
21112111
hasintersect(widenconst(order), Symbol) || return false
21122112
hasintersect(widenconst(unwrapva(boundscheck)), Bool) || return false
21132113
return true
@@ -2203,7 +2203,7 @@ function memoryref_builtin_common_nothrow(argtypes::Vector{Any})
22032203
idx = widenconst(argtypes[2])
22042204
idx Int || return false
22052205
boundscheck Bool || return false
2206-
memtype GenericMemoryRef || return false
2206+
memtype Union{GenericMemory, GenericMemoryRef} || return false
22072207
# If we have @inbounds (last argument is false), we're allowed to assume
22082208
# we don't throw bounds errors.
22092209
if isa(boundscheck, Const)

base/boot.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ const undef = UndefInitializer()
591591
(self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0)
592592

593593
memoryref(mem::GenericMemory) = memoryrefnew(mem)
594-
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(memoryrefnew(mem), Int(i), @_boundscheck)
594+
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(mem, Int(i), @_boundscheck)
595595
memoryref(ref::GenericMemoryRef, i::Integer) = memoryrefnew(ref, Int(i), @_boundscheck)
596596
GenericMemoryRef(mem::GenericMemory) = memoryref(mem)
597597
GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(mem, i)

base/essentials.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ default_access_order(a::GenericMemoryRef{:atomic}) = :monotonic
394394
function getindex(A::GenericMemory, i::Int)
395395
@_noub_if_noinbounds_meta
396396
(@_boundscheck) && _checkbounds_array(A, i)
397-
memoryrefget(memoryrefnew(memoryrefnew(A), i, false), default_access_order(A), false)
397+
memoryrefget(memoryrefnew(A, i, false), default_access_order(A), false)
398398
end
399399

400400
getindex(A::GenericMemoryRef) = memoryrefget(A, default_access_order(A), @_boundscheck)
@@ -972,7 +972,7 @@ function setindex!(A::Array{Any}, @nospecialize(x), i::Int)
972972
memoryrefset!(memoryrefnew(getfield(A, :ref), i, false), x, :not_atomic, false)
973973
return A
974974
end
975-
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryrefnew(memoryrefnew(A), i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
975+
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryrefnew(A, i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
976976
setindex!(A::MemoryRef{T}, x) where {T} = (memoryrefset!(A, convert(T, x), :not_atomic, @_boundscheck); A)
977977
setindex!(A::MemoryRef{Any}, @nospecialize(x)) = (memoryrefset!(A, x, :not_atomic, @_boundscheck); A)
978978

src/builtins.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,30 +1765,45 @@ JL_CALLABLE(jl_f_memoryrefnew)
17651765
return (jl_value_t*)jl_new_memoryref(typ, m, m->ptr);
17661766
}
17671767
else {
1768-
JL_TYPECHK(memoryrefnew, genericmemoryref, args[0]);
17691768
JL_TYPECHK(memoryrefnew, long, args[1]);
17701769
if (nargs == 3)
17711770
JL_TYPECHK(memoryrefnew, bool, args[2]);
1772-
jl_genericmemoryref_t *m = (jl_genericmemoryref_t*)args[0];
17731771
size_t i = jl_unbox_long(args[1]) - 1;
1774-
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m->mem))->layout;
1775-
char *data = (char*)m->ptr_or_offset;
1772+
char *data;
1773+
if(jl_is_genericmemory(args[0])) {
1774+
jl_genericmemory_t *m = (jl_genericmemory_t*)args[0];
1775+
jl_value_t *typ = jl_apply_type((jl_value_t*)jl_genericmemoryref_type, jl_svec_data(((jl_datatype_t*)jl_typetagof(m))->parameters), 3);
1776+
JL_GC_PROMISE_ROOTED(typ); // it is a concrete type
1777+
if (i >= m->length)
1778+
jl_bounds_error((jl_value_t*)m, args[1]);
1779+
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m))->layout;
1780+
if (layout->flags.arrayelem_isunion || layout->size == 0)
1781+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)i);
1782+
else if (layout->flags.arrayelem_isboxed)
1783+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)m->ptr + sizeof(jl_value_t*)*i);
1784+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)m->ptr + layout->size*i);
1785+
}
1786+
JL_TYPECHK(memoryrefnew, genericmemoryref, args[0]);
1787+
jl_genericmemoryref_t *m = (jl_genericmemoryref_t*)args[0];
1788+
jl_genericmemory_t *mem = m->mem;
1789+
data = (char*)m->ptr_or_offset;
1790+
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(mem))->layout;
17761791
if (layout->flags.arrayelem_isboxed) {
1777-
if (((data - (char*)m->mem->ptr) / sizeof(jl_value_t*)) + i >= m->mem->length)
1792+
if (((data - (char*)mem->ptr) / sizeof(jl_value_t*)) + i >= mem->length)
17781793
jl_bounds_error((jl_value_t*)m, args[1]);
17791794
data += sizeof(jl_value_t*) * i;
17801795
}
17811796
else if (layout->flags.arrayelem_isunion || layout->size == 0) {
1782-
if ((size_t)data + i >= m->mem->length)
1797+
if ((size_t)data + i >= mem->length)
17831798
jl_bounds_error((jl_value_t*)m, args[1]);
17841799
data += i;
17851800
}
17861801
else {
1787-
if (((data - (char*)m->mem->ptr) / layout->size) + i >= m->mem->length)
1802+
if (((data - (char*)mem->ptr) / layout->size) + i >= mem->length)
17881803
jl_bounds_error((jl_value_t*)m, args[1]);
17891804
data += layout->size * i;
17901805
}
1791-
return (jl_value_t*)jl_new_memoryref((jl_value_t*)jl_typetagof(m), m->mem, data);
1806+
return (jl_value_t*)jl_new_memoryref((jl_value_t*)jl_typetagof(m), mem, data);
17921807
}
17931808
}
17941809

src/codegen.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4138,16 +4138,25 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
41384138

41394139
else if (f == BUILTIN(memoryrefnew) && (nargs == 2 || nargs == 3)) {
41404140
const jl_cgval_t &ref = argv[1];
4141-
jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ);
4142-
if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) {
4143-
mty_dt = jl_field_type_concrete((jl_datatype_t*)mty_dt, 1);
4144-
const jl_datatype_layout_t *layout = ((jl_datatype_t*)mty_dt)->layout;
4141+
jl_datatype_t *mty_dt = (jl_datatype_t*)jl_unwrap_unionall(ref.typ);
4142+
if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type((jl_value_t*)mty_dt)) {
4143+
mty_dt = (jl_datatype_t*)jl_field_type_concrete(mty_dt, 1);
4144+
const jl_datatype_layout_t *layout = mty_dt->layout;
41454145
jl_value_t *boundscheck = nargs == 3 ? argv[3].constant : nullptr;
41464146
if (nargs == 3)
41474147
emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefnew");
41484148
*ret = emit_memoryref(ctx, ref, argv[2], boundscheck, layout);
41494149
return true;
41504150
}
4151+
if (jl_is_genericmemory_type(mty_dt) && jl_is_concrete_type((jl_value_t*)mty_dt)) {
4152+
const jl_datatype_layout_t *layout = mty_dt->layout;
4153+
jl_value_t *boundscheck = nargs == 3 ? argv[3].constant : nullptr;
4154+
if (nargs == 3)
4155+
emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefnew");
4156+
jl_value_t *typ = jl_apply_type((jl_value_t*)jl_genericmemoryref_type, jl_svec_data(mty_dt->parameters), jl_svec_len(mty_dt->parameters));
4157+
*ret = emit_memoryref(ctx, _emit_memoryref(ctx, ref, layout, typ), argv[2], boundscheck, layout);
4158+
return true;
4159+
}
41514160
}
41524161

41534162
else if (f == BUILTIN(memoryrefoffset) && nargs == 1) {

0 commit comments

Comments
 (0)