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

Revert ConstantArray changes. #331

Merged
merged 4 commits into from
Mar 21, 2023
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
4 changes: 2 additions & 2 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ version = "1.4.1"

[[LLVMExtra_jll]]
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"]
git-tree-sha1 = "e46e3a40daddcbe851f86db0ec4a4a3d4badf800"
git-tree-sha1 = "070e4b5b65827f82c16ae0916376cb47377aa1b5"
uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab"
version = "0.0.19+0"
version = "0.0.18+0"

[[LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "LLVM"
uuid = "929cbde3-209d-540e-8aea-75f648917ca0"
version = "4.17.0"
version = "4.17.1"

[deps]
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Expand All @@ -11,5 +11,5 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[compat]
CEnum = "0.2, 0.3, 0.4"
LLVMExtra_jll = "=0.0.19"
LLVMExtra_jll = "=0.0.18"
julia = "1.6"
3 changes: 0 additions & 3 deletions deps/LLVMExtra/include/LLVMExtra.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,5 @@ void LLVMReplaceMDNodeOperandWith(LLVMMetadataRef MD, unsigned I, LLVMMetadataRe
LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C);
#endif

// constant data
LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const void *Data, unsigned NumElements);

LLVM_C_EXTERN_C_END
#endif
5 changes: 0 additions & 5 deletions deps/LLVMExtra/lib/llvm-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,3 @@ LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C) {
return unwrap(C)->supportsTypedPointers();
}
#endif

LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const void *Data, unsigned NumElements) {
StringRef S((const char *)Data, NumElements * unwrap(ElementTy)->getPrimitiveSizeInBits() / 8);
return wrap(ConstantDataArray::getRaw(S, NumElements, unwrap(ElementTy)));
}
4 changes: 0 additions & 4 deletions lib/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,3 @@ function LLVMContextSupportsTypedPointers(Ctx)
ccall((:LLVMContextSupportsTypedPointers, libLLVMExtra), LLVMBool, (LLVMContextRef,), Ctx)
end
end

function LLVMConstDataArray(ElementTy, Data, NumElements)
ccall((:LLVMConstDataArray, libLLVMExtra), LLVMValueRef, (LLVMTypeRef, Ptr{Cvoid}, Cuint), ElementTy, Data, NumElements)
end
27 changes: 0 additions & 27 deletions src/core/module.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,30 +267,3 @@ function Base.setindex!(iter::ModuleFlagDict, val::Metadata,
(name, behavior)::Tuple{String, API.LLVMModuleFlagBehavior})
API.LLVMAddModuleFlag(iter.mod, behavior, name, length(name), val)
end


## sdk version

export sdk_version, sdk_version!

function sdk_version!(mod::Module, version::VersionNumber)
entries = Int32[version.major]
if version.minor != 0 || version.patch != 0
push!(entries, version.minor)
if version.patch != 0
push!(entries, version.patch)
end
# cannot represent prerelease or build metadata
end
md = Metadata(ConstantDataArray(entries; ctx=context(mod)))

flags(mod)["SDK Version", LLVM.API.LLVMModuleFlagBehaviorWarning] = md
end

function sdk_version(mod::Module)
haskey(flags(mod), "SDK Version") || return nothing
md = flags(mod)["SDK Version"]
c = Value(md; ctx=context(mod))
entries = collect(c)
VersionNumber(map(val->convert(Int, val), entries)...)
end
2 changes: 1 addition & 1 deletion src/core/type.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function ArrayType(eltyp::LLVMType, count)
return ArrayType(API.LLVMArrayType(eltyp, count))
end

Base.length(arrtyp::ArrayType) = Int(API.LLVMGetArrayLength(arrtyp))
Base.length(arrtyp::ArrayType) = API.LLVMGetArrayLength(arrtyp)

Base.isempty(@nospecialize(T::ArrayType)) = length(T) == 0 || isempty(eltype(T))

Expand Down
72 changes: 11 additions & 61 deletions src/core/value/constant.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,67 +112,17 @@ Base.convert(::Type{T}, val::ConstantFP) where {T<:AbstractFloat} =
convert(T, API.LLVMConstRealGetDouble(val, Ref{API.LLVMBool}()))


# sequential data
# sequential

export ConstantDataSequential, ConstantDataArray, ConstantDataVector

abstract type ConstantDataSequential <: Constant end

# ConstantData can only contain primitive types (1/2/4/8 byte integers, float/half),
# as opposed to ConstantAggregate which can contain arbitrary LLVM values.
#
# however, LLVM seems to use both array types interchangeably, e.g., constructing
# a ConstArray through LLVMConstArray may return a ConstantDataArray (presumably as an
# optimization, when the data can be represented as densely packed primitive values).
# because of that, ConstantDataArray and ConstantArray need to behave the same way,
# concretely, indexing a ConstantDataArray has to return LLVM constant values...
#
# XXX: maybe we should just not expose ConstantDataArray then?
# one advantage of keeping them separate is that creating a ConstantDataArray
# is much cheaper (we should also be able to iterate much more efficiently,
# but cannot support that as explained above).

# array interface
Base.eltype(cda::ConstantDataSequential) = llvmeltype(cda)
Base.length(cda::ConstantDataSequential) = length(llvmtype(cda))
Base.size(cda::ConstantDataSequential) = (length(cda),)
function Base.getindex(cda::ConstantDataSequential, idx::Integer)
@boundscheck 1 <= idx <= length(cda) || throw(BoundsError(cda, idx))
Value(API.LLVMGetElementAsConstant(cda, idx-1))
end
function Base.collect(cda::ConstantDataSequential)
constants = Array{Value}(undef, length(cda))
for i in 1:length(cda)
@inbounds constants[i] = cda[i]
end
return constants
end

@checked struct ConstantDataArray <: ConstantDataSequential
ref::API.LLVMValueRef
end
register(ConstantDataArray, API.LLVMConstantDataArrayValueKind)

function ConstantDataArray(typ::LLVMType, data::Array{T}) where {T <: Union{Integer, AbstractFloat}}
# TODO: can we look up the primitive size of the LLVM type?
# use that to assert it matches the Julia element type.
return ConstantDataArray(API.LLVMConstDataArray(typ, data, length(data)))
end

# shorthands with arrays of plain Julia data
# FIXME: duplicates the ConstantInt/ConstantFP conversion rules
# XXX: X[X(...)] instead of X.(...) because of empty-container inference
ConstantDataArray(data::AbstractVector{T}; ctx::Context) where {T<:Integer} =
ConstantDataArray(IntType(sizeof(T)*8; ctx), data)
ConstantDataArray(data::AbstractVector{Core.Bool}; ctx::Context) =
ConstantDataArray(Int1Type(ctx), data)
ConstantDataArray(data::AbstractVector{Float16}; ctx::Context) =
ConstantDataArray(HalfType(ctx), data)
ConstantDataArray(data::AbstractVector{Float32}; ctx::Context) =
ConstantDataArray(FloatType(ctx), data)
ConstantDataArray(data::AbstractVector{Float64}; ctx::Context) =
ConstantDataArray(DoubleType(ctx), data)

@checked struct ConstantDataVector <: ConstantDataSequential
ref::API.LLVMValueRef
end
Expand Down Expand Up @@ -212,14 +162,16 @@ export ConstantArray
ref::API.LLVMValueRef
end
register(ConstantArray, API.LLVMConstantArrayValueKind)
register(ConstantArray, API.LLVMConstantDataArrayValueKind)

ConstantArrayOrAggregateZero(value) = Value(value)::Union{ConstantArray,ConstantAggregateZero}

# generic constructor taking an array of constants
function ConstantArray(typ::LLVMType, data::AbstractArray{T,N}=T[]) where {T<:Constant,N}
@assert all(x->x==typ, llvmtype.(data))

if N == 1
# XXX: this can return a ConstDataArray (presumably as an optimization?)
return Value(API.LLVMConstArray(typ, Array(data), length(data)))
return ConstantArrayOrAggregateZero(API.LLVMConstArray(typ, Array(data), length(data)))
end

ca_vec = map(x->ConstantArray(typ, x), eachslice(data, dims=1))
Expand All @@ -231,15 +183,15 @@ end
# shorthands with arrays of plain Julia data
# FIXME: duplicates the ConstantInt/ConstantFP conversion rules
# XXX: X[X(...)] instead of X.(...) because of empty-container inference
ConstantArray(data::AbstractArray{T}; ctx::Context) where {T<:Integer} =
ConstantArray(data::AbstractArray{T,N}; ctx::Context) where {T<:Integer,N} =
ConstantArray(IntType(sizeof(T)*8; ctx), ConstantInt[ConstantInt(x; ctx) for x in data])
ConstantArray(data::AbstractArray{Core.Bool}; ctx::Context) =
ConstantArray(data::AbstractArray{Core.Bool,N}; ctx::Context) where {N} =
ConstantArray(Int1Type(ctx), ConstantInt[ConstantInt(x; ctx) for x in data])
ConstantArray(data::AbstractArray{Float16}; ctx::Context) =
ConstantArray(data::AbstractArray{Float16,N}; ctx::Context) where {N} =
ConstantArray(HalfType(ctx), ConstantFP[ConstantFP(x; ctx) for x in data])
ConstantArray(data::AbstractArray{Float32}; ctx::Context) =
ConstantArray(data::AbstractArray{Float32,N}; ctx::Context) where {N} =
ConstantArray(FloatType(ctx), ConstantFP[ConstantFP(x; ctx) for x in data])
ConstantArray(data::AbstractArray{Float64}; ctx::Context) =
ConstantArray(data::AbstractArray{Float64,N}; ctx::Context) where {N} =
ConstantArray(DoubleType(ctx), ConstantFP[ConstantFP(x; ctx) for x in data])

# convert back to known array types
Expand Down Expand Up @@ -274,9 +226,7 @@ function Base.getindex(ca::ConstantArray, idx::Integer...)
I = CartesianIndices(size(ca))[idx...]
for i in Tuple(I)
if isempty(operands(ca))
# XXX: is this valid? LLVMGetElementAsConstant is meant to be used with
# Constant*Data*Arrays, not ConstantArrays
ca = Value(API.LLVMGetElementAsConstant(ca, i-1))
ca = LLVM.Value(API.LLVMGetElementAsConstant(ca, i-1))
else
ca = (Base.@_propagate_inbounds_meta; operands(ca)[i])
end
Expand Down
50 changes: 11 additions & 39 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -419,23 +419,29 @@ end
end


@testset "array aggregate constants" begin
@testset "array constants" begin

# from Julia values
let
vec = Int128[1,2,3,4]
vec = Int32[1,2,3,4]
ca = ConstantArray(vec; ctx)
@test ca isa ConstantArray
@test size(vec) == size(ca)
@test length(vec) == length(ca)
@test ca[1] == ConstantInt(vec[1]; ctx)
@test collect(ca) == ConstantInt.(vec; ctx)
end
let
vec = Float32[1.1f0,2.2f0,3.3f0,4.4f0]
ca = ConstantArray(vec; ctx)
@test size(vec) == size(ca)
@test length(vec) == length(ca)
@test ca[1] == ConstantFP(vec[1]; ctx)
@test collect(ca) == ConstantFP.(vec; ctx)
end
let
# tests for ConstantAggregateZero, constructed indirectly.
# should behave similarly to ConstantArray since it can get returned there.
ca = ConstantArray(Int[]; ctx)
@test ca isa ConstantAggregateZero
@test size(ca) == (0,)
@test length(ca) == 0
@test isempty(collect(ca))
Expand All @@ -452,7 +458,7 @@ end

end

@testset "struct aggregate constants" begin
@testset "struct constants" begin

# from Julia values
let
Expand Down Expand Up @@ -507,36 +513,6 @@ end
end

end


@testset "array data constants" begin

let
vec = Int32[1,2,3,4]
eltyp = LLVM.Int32Type(ctx)
cda = ConstantDataArray(eltyp, vec)
@test cda isa ConstantDataArray
@test llvmtype(cda) == LLVM.ArrayType(eltyp, 4)
@test collect(cda) == ConstantInt.(vec; ctx)
end

# from Julia values
for T in [Int8, Int16, Int32, Int64]
vec = T[1,2,3,4]
cda = ConstantDataArray(vec; ctx)
@test cda isa ConstantDataArray
@test size(vec) == size(cda)
@test collect(cda) == ConstantInt.(vec; ctx)
end
for T in [Float32, Float64]
vec = T[1,2,3,4]
cda = ConstantDataArray(vec; ctx)
@test cda isa ConstantDataArray
@test size(vec) == size(cda)
@test collect(cda) == ConstantFP.(vec; ctx)
end

end
end

# constant expressions
Expand Down Expand Up @@ -1015,10 +991,6 @@ end

@test mod_flags["foobar"] == md
@test_throws KeyError mod_flags["foobaz"]

@test sdk_version(mod) === nothing
sdk_version!(mod, v"1.2.3")
@test sdk_version(mod) == v"1.2.3"
end

# metadata iteration
Expand Down