@@ -112,67 +112,17 @@ Base.convert(::Type{T}, val::ConstantFP) where {T<:AbstractFloat} =
112112 convert (T, API. LLVMConstRealGetDouble (val, Ref {API.LLVMBool} ()))
113113
114114
115- # sequential data
115+ # sequential
116116
117117export ConstantDataSequential, ConstantDataArray, ConstantDataVector
118118
119119abstract type ConstantDataSequential <: Constant end
120120
121- # ConstantData can only contain primitive types (1/2/4/8 byte integers, float/half),
122- # as opposed to ConstantAggregate which can contain arbitrary LLVM values.
123- #
124- # however, LLVM seems to use both array types interchangeably, e.g., constructing
125- # a ConstArray through LLVMConstArray may return a ConstantDataArray (presumably as an
126- # optimization, when the data can be represented as densely packed primitive values).
127- # because of that, ConstantDataArray and ConstantArray need to behave the same way,
128- # concretely, indexing a ConstantDataArray has to return LLVM constant values...
129- #
130- # XXX : maybe we should just not expose ConstantDataArray then?
131- # one advantage of keeping them separate is that creating a ConstantDataArray
132- # is much cheaper (we should also be able to iterate much more efficiently,
133- # but cannot support that as explained above).
134-
135- # array interface
136- Base. eltype (cda:: ConstantDataSequential ) = llvmeltype (cda)
137- Base. length (cda:: ConstantDataSequential ) = length (llvmtype (cda))
138- Base. size (cda:: ConstantDataSequential ) = (length (cda),)
139- function Base. getindex (cda:: ConstantDataSequential , idx:: Integer )
140- @boundscheck 1 <= idx <= length (cda) || throw (BoundsError (cda, idx))
141- Value (API. LLVMGetElementAsConstant (cda, idx- 1 ))
142- end
143- function Base. collect (cda:: ConstantDataSequential )
144- constants = Array {Value} (undef, length (cda))
145- for i in 1 : length (cda)
146- @inbounds constants[i] = cda[i]
147- end
148- return constants
149- end
150-
151121@checked struct ConstantDataArray <: ConstantDataSequential
152122 ref:: API.LLVMValueRef
153123end
154124register (ConstantDataArray, API. LLVMConstantDataArrayValueKind)
155125
156- function ConstantDataArray (typ:: LLVMType , data:: Array{T} ) where {T <: Union{Integer, AbstractFloat} }
157- # TODO : can we look up the primitive size of the LLVM type?
158- # use that to assert it matches the Julia element type.
159- return ConstantDataArray (API. LLVMConstDataArray (typ, data, length (data)))
160- end
161-
162- # shorthands with arrays of plain Julia data
163- # FIXME : duplicates the ConstantInt/ConstantFP conversion rules
164- # XXX : X[X(...)] instead of X.(...) because of empty-container inference
165- ConstantDataArray (data:: AbstractVector{T} ; ctx:: Context ) where {T<: Integer } =
166- ConstantDataArray (IntType (sizeof (T)* 8 ; ctx), data)
167- ConstantDataArray (data:: AbstractVector{Core.Bool} ; ctx:: Context ) =
168- ConstantDataArray (Int1Type (ctx), data)
169- ConstantDataArray (data:: AbstractVector{Float16} ; ctx:: Context ) =
170- ConstantDataArray (HalfType (ctx), data)
171- ConstantDataArray (data:: AbstractVector{Float32} ; ctx:: Context ) =
172- ConstantDataArray (FloatType (ctx), data)
173- ConstantDataArray (data:: AbstractVector{Float64} ; ctx:: Context ) =
174- ConstantDataArray (DoubleType (ctx), data)
175-
176126@checked struct ConstantDataVector <: ConstantDataSequential
177127 ref:: API.LLVMValueRef
178128end
@@ -212,14 +162,16 @@ export ConstantArray
212162 ref:: API.LLVMValueRef
213163end
214164register (ConstantArray, API. LLVMConstantArrayValueKind)
165+ register (ConstantArray, API. LLVMConstantDataArrayValueKind)
166+
167+ ConstantArrayOrAggregateZero (value) = Value (value):: Union{ConstantArray,ConstantAggregateZero}
215168
216169# generic constructor taking an array of constants
217170function ConstantArray (typ:: LLVMType , data:: AbstractArray{T,N} = T[]) where {T<: Constant ,N}
218171 @assert all (x-> x== typ, llvmtype .(data))
219172
220173 if N == 1
221- # XXX : this can return a ConstDataArray (presumably as an optimization?)
222- return Value (API. LLVMConstArray (typ, Array (data), length (data)))
174+ return ConstantArrayOrAggregateZero (API. LLVMConstArray (typ, Array (data), length (data)))
223175 end
224176
225177 ca_vec = map (x-> ConstantArray (typ, x), eachslice (data, dims= 1 ))
@@ -231,15 +183,15 @@ end
231183# shorthands with arrays of plain Julia data
232184# FIXME : duplicates the ConstantInt/ConstantFP conversion rules
233185# XXX : X[X(...)] instead of X.(...) because of empty-container inference
234- ConstantArray (data:: AbstractArray{T} ; ctx:: Context ) where {T<: Integer } =
186+ ConstantArray (data:: AbstractArray{T,N } ; ctx:: Context ) where {T<: Integer ,N } =
235187 ConstantArray (IntType (sizeof (T)* 8 ; ctx), ConstantInt[ConstantInt (x; ctx) for x in data])
236- ConstantArray (data:: AbstractArray{Core.Bool} ; ctx:: Context ) =
188+ ConstantArray (data:: AbstractArray{Core.Bool,N } ; ctx:: Context ) where {N} =
237189 ConstantArray (Int1Type (ctx), ConstantInt[ConstantInt (x; ctx) for x in data])
238- ConstantArray (data:: AbstractArray{Float16} ; ctx:: Context ) =
190+ ConstantArray (data:: AbstractArray{Float16,N } ; ctx:: Context ) where {N} =
239191 ConstantArray (HalfType (ctx), ConstantFP[ConstantFP (x; ctx) for x in data])
240- ConstantArray (data:: AbstractArray{Float32} ; ctx:: Context ) =
192+ ConstantArray (data:: AbstractArray{Float32,N } ; ctx:: Context ) where {N} =
241193 ConstantArray (FloatType (ctx), ConstantFP[ConstantFP (x; ctx) for x in data])
242- ConstantArray (data:: AbstractArray{Float64} ; ctx:: Context ) =
194+ ConstantArray (data:: AbstractArray{Float64,N } ; ctx:: Context ) where {N} =
243195 ConstantArray (DoubleType (ctx), ConstantFP[ConstantFP (x; ctx) for x in data])
244196
245197# convert back to known array types
@@ -274,9 +226,7 @@ function Base.getindex(ca::ConstantArray, idx::Integer...)
274226 I = CartesianIndices (size (ca))[idx... ]
275227 for i in Tuple (I)
276228 if isempty (operands (ca))
277- # XXX : is this valid? LLVMGetElementAsConstant is meant to be used with
278- # Constant*Data*Arrays, not ConstantArrays
279- ca = Value (API. LLVMGetElementAsConstant (ca, i- 1 ))
229+ ca = LLVM. Value (API. LLVMGetElementAsConstant (ca, i- 1 ))
280230 else
281231 ca = (Base. @_propagate_inbounds_meta ; operands (ca)[i])
282232 end
0 commit comments