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

inference: thread lattice through memoryop type check #52773

Merged
merged 1 commit into from
Jan 7, 2024
Merged
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
18 changes: 10 additions & 8 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2084,12 +2084,13 @@ function array_type_undefable(@nospecialize(arytype))
return true
end

@nospecs function memoryset_typecheck(memtype, elemtype)
@nospecs function memoryset_typecheck(𝕃::AbstractLattice, memtype, elemtype)
# Check that we can determine the element type
isa(memtype, DataType) || return false
elemtype_expected = memoryref_elemtype(memtype)
elemtype_expected === Union{} && return false
# Check that the element type is compatible with the element we're assigning
= Core.Compiler.:(𝕃)
Copy link
Member

Choose a reason for hiding this comment

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

Aren't we already in Core.Compiler here?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a hack to use the same symbol as a binary operator in the local context.

Copy link
Member

Choose a reason for hiding this comment

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

A little ugly, but I guess I don't care.

Copy link
Member

Choose a reason for hiding this comment

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

Should be just Compiler.⊑ then, since Core.Compiler might be a different module from this

Copy link
Member Author

Choose a reason for hiding this comment

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

tfuncs.jl is loaded only within Core.Compiler, but let's make this clean in another PR.

Copy link
Member

Choose a reason for hiding this comment

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

I often load other Compilers that aren't the one in Core

elemtype elemtype_expected || return false
return true
end
Expand Down Expand Up @@ -2122,17 +2123,17 @@ function memoryref_builtin_common_nothrow(argtypes::Vector{Any})
end
end

function memoryrefop_builtin_common_nothrow(argtypes::Vector{Any}, @nospecialize f)
function memoryrefop_builtin_common_nothrow(𝕃::AbstractLattice, argtypes::Vector{Any}, @nospecialize f)
ismemoryset = f === memoryrefset!
nargs = ismemoryset ? 4 : 3
length(argtypes) == nargs || return false
order = argtypes[2 + ismemoryset]
boundscheck = argtypes[3 + ismemoryset]
memtype = widenconst(argtypes[1])
memoryref_builtin_common_typecheck(boundscheck, memtype, order) || return false
memoryref_builtin_common_typecheck(𝕃, boundscheck, memtype, order) || return false
if ismemoryset
# Additionally check element type compatibility
memoryset_typecheck(memtype, argtypes[2]) || return false
memoryset_typecheck(𝕃, memtype, argtypes[2]) || return false
elseif f === memoryrefget
# If we could potentially throw undef ref errors, bail out now.
array_type_undefable(memtype) && return false
Expand All @@ -2147,7 +2148,8 @@ function memoryrefop_builtin_common_nothrow(argtypes::Vector{Any}, @nospecialize
return false
end

@nospecs function memoryref_builtin_common_typecheck(boundscheck, memtype, order)
@nospecs function memoryref_builtin_common_typecheck(𝕃::AbstractLattice, boundscheck, memtype, order)
= Core.Compiler.:(𝕃)
return boundscheck Bool && memtype GenericMemoryRef && order Symbol
end

Expand All @@ -2161,11 +2163,11 @@ end
memtype = widenconst(argtypes[1])
return memtype GenericMemoryRef
elseif f === memoryrefset!
return memoryrefop_builtin_common_nothrow(argtypes, f)
return memoryrefop_builtin_common_nothrow(𝕃, argtypes, f)
elseif f === memoryrefget
return memoryrefop_builtin_common_nothrow(argtypes, f)
return memoryrefop_builtin_common_nothrow(𝕃, argtypes, f)
elseif f === memoryref_isassigned
return memoryrefop_builtin_common_nothrow(argtypes, f)
return memoryrefop_builtin_common_nothrow(𝕃, argtypes, f)
elseif f === Core._expr
length(argtypes) >= 1 || return false
return argtypes[1] Symbol
Expand Down