@@ -112,67 +112,17 @@ Base.convert(::Type{T}, val::ConstantFP) where {T<:AbstractFloat} =
112
112
convert (T, API. LLVMConstRealGetDouble (val, Ref {API.LLVMBool} ()))
113
113
114
114
115
- # sequential data
115
+ # sequential
116
116
117
117
export ConstantDataSequential, ConstantDataArray, ConstantDataVector
118
118
119
119
abstract type ConstantDataSequential <: Constant end
120
120
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
-
151
121
@checked struct ConstantDataArray <: ConstantDataSequential
152
122
ref:: API.LLVMValueRef
153
123
end
154
124
register (ConstantDataArray, API. LLVMConstantDataArrayValueKind)
155
125
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
-
176
126
@checked struct ConstantDataVector <: ConstantDataSequential
177
127
ref:: API.LLVMValueRef
178
128
end
@@ -212,14 +162,16 @@ export ConstantArray
212
162
ref:: API.LLVMValueRef
213
163
end
214
164
register (ConstantArray, API. LLVMConstantArrayValueKind)
165
+ register (ConstantArray, API. LLVMConstantDataArrayValueKind)
166
+
167
+ ConstantArrayOrAggregateZero (value) = Value (value):: Union{ConstantArray,ConstantAggregateZero}
215
168
216
169
# generic constructor taking an array of constants
217
170
function ConstantArray (typ:: LLVMType , data:: AbstractArray{T,N} = T[]) where {T<: Constant ,N}
218
171
@assert all (x-> x== typ, llvmtype .(data))
219
172
220
173
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)))
223
175
end
224
176
225
177
ca_vec = map (x-> ConstantArray (typ, x), eachslice (data, dims= 1 ))
@@ -231,15 +183,15 @@ end
231
183
# shorthands with arrays of plain Julia data
232
184
# FIXME : duplicates the ConstantInt/ConstantFP conversion rules
233
185
# 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 } =
235
187
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} =
237
189
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} =
239
191
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} =
241
193
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} =
243
195
ConstantArray (DoubleType (ctx), ConstantFP[ConstantFP (x; ctx) for x in data])
244
196
245
197
# convert back to known array types
@@ -274,9 +226,7 @@ function Base.getindex(ca::ConstantArray, idx::Integer...)
274
226
I = CartesianIndices (size (ca))[idx... ]
275
227
for i in Tuple (I)
276
228
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 ))
280
230
else
281
231
ca = (Base. @_propagate_inbounds_meta ; operands (ca)[i])
282
232
end
0 commit comments