@@ -158,13 +158,56 @@ class ConstExprEmitter
158158
159159// TODO(cir): this can be shared with LLVM's codegen
160160static QualType getNonMemoryType (CIRGenModule &cgm, QualType type) {
161- if (auto at = type->getAs <AtomicType>()) {
161+ if (const auto * at = type->getAs <AtomicType>()) {
162162 return cgm.getASTContext ().getQualifiedType (at->getValueType (),
163163 type.getQualifiers ());
164164 }
165165 return type;
166166}
167167
168+ static mlir::Attribute
169+ emitArrayConstant (CIRGenModule &cgm, mlir::Type desiredType,
170+ mlir::Type commonElementType, unsigned arrayBound,
171+ SmallVectorImpl<mlir::TypedAttr> &elements,
172+ mlir::TypedAttr filter) {
173+ const auto &builder = cgm.getBuilder ();
174+
175+ unsigned nonzeroLength = arrayBound;
176+ if (elements.size () < nonzeroLength && builder.isNullValue (filter))
177+ nonzeroLength = elements.size ();
178+
179+ if (nonzeroLength == elements.size ()) {
180+ while (nonzeroLength > 0 &&
181+ builder.isNullValue (elements[nonzeroLength - 1 ]))
182+ --nonzeroLength;
183+ }
184+
185+ if (nonzeroLength == 0 )
186+ return cir::ZeroAttr::get (builder.getContext (), desiredType);
187+
188+ const unsigned trailingZeroes = arrayBound - nonzeroLength;
189+ if (trailingZeroes >= 8 ) {
190+ if (elements.size () < nonzeroLength)
191+ cgm.errorNYI (" missing initializer for non-zero element" );
192+ } else if (elements.size () != arrayBound) {
193+ elements.resize (arrayBound, filter);
194+
195+ if (filter.getType () != commonElementType)
196+ cgm.errorNYI (
197+ " array filter type should always be the same as element type" );
198+ }
199+
200+ SmallVector<mlir::Attribute, 4 > eles;
201+ eles.reserve (elements.size ());
202+
203+ for (const auto &element : elements)
204+ eles.push_back (element);
205+
206+ return cir::ConstArrayAttr::get (
207+ cir::ArrayType::get (builder.getContext (), commonElementType, arrayBound),
208+ mlir::ArrayAttr::get (builder.getContext (), eles));
209+ }
210+
168211// ===----------------------------------------------------------------------===//
169212// ConstantEmitter
170213// ===----------------------------------------------------------------------===//
@@ -271,16 +314,61 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
271314 cgm.getASTContext ().getTargetInfo ().useFP16ConversionIntrinsics ()) {
272315 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate half" );
273316 return {};
274- } else {
275- mlir::Type ty = cgm.convertType (destType);
276- assert (mlir::isa<cir::CIRFPTypeInterface>(ty) &&
277- " expected floating-point type" );
278- return cgm.getBuilder ().getAttr <cir::FPAttr>(ty, init);
279317 }
318+
319+ mlir::Type ty = cgm.convertType (destType);
320+ assert (mlir::isa<cir::CIRFPTypeInterface>(ty) &&
321+ " expected floating-point type" );
322+ return cgm.getBuilder ().getAttr <cir::FPAttr>(ty, init);
280323 }
281324 case APValue::Array: {
282- cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate array" );
283- return {};
325+ const ArrayType *arrayTy = cgm.getASTContext ().getAsArrayType (destType);
326+ const QualType arrayElementTy = arrayTy->getElementType ();
327+ const unsigned numElements = value.getArraySize ();
328+ const unsigned numInitElts = value.getArrayInitializedElts ();
329+
330+ mlir::Attribute filter;
331+ if (value.hasArrayFiller ()) {
332+ filter =
333+ tryEmitPrivate (value.getArrayFiller (), arrayTy->getElementType ());
334+ if (!filter)
335+ return {};
336+ }
337+
338+ SmallVector<mlir::TypedAttr, 16 > elements;
339+ if (filter && builder.isNullValue (filter))
340+ elements.reserve (numInitElts + 1 );
341+ else
342+ elements.reserve (numInitElts);
343+
344+ mlir::Type commonElementType;
345+ for (unsigned i = 0 ; i < numInitElts; ++i) {
346+ const APValue &arrayElement = value.getArrayInitializedElt (i);
347+ const mlir::Attribute element =
348+ tryEmitPrivateForMemory (arrayElement, arrayElementTy);
349+ if (!element)
350+ return {};
351+
352+ const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
353+ if (i == 0 )
354+ commonElementType = elementTyped.getType ();
355+ else if (elementTyped.getType () != commonElementType) {
356+ cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate Array without common "
357+ " element type" );
358+ return {};
359+ }
360+
361+ elements.push_back (elementTyped);
362+ }
363+
364+ mlir::TypedAttr typedFilter =
365+ llvm::dyn_cast_or_null<mlir::TypedAttr>(filter);
366+ if (filter && !typedFilter)
367+ cgm.errorNYI (" array filter should always be typed" );
368+
369+ mlir::Type desiredType = cgm.convertType (destType);
370+ return emitArrayConstant (cgm, desiredType, commonElementType, numElements,
371+ elements, typedFilter);
284372 }
285373 case APValue::Vector: {
286374 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate vector" );
@@ -290,9 +378,23 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
290378 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate member pointer" );
291379 return {};
292380 }
293- case APValue::LValue:
294- cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate lvalue" );
381+ case APValue::LValue: {
382+
383+ if (value.getLValueBase ()) {
384+ cgm.errorNYI (" non-null pointer initialization" );
385+ } else {
386+
387+ mlir::Type desiredType = cgm.convertType (destType);
388+ if (const cir::PointerType ptrType =
389+ mlir::dyn_cast<cir::PointerType>(desiredType)) {
390+ return builder.getConstPtrAttr (ptrType,
391+ value.getLValueOffset ().getQuantity ());
392+ } else {
393+ llvm_unreachable (" non-pointer variable initialized with a pointer" );
394+ }
395+ }
295396 return {};
397+ }
296398 case APValue::Struct:
297399 case APValue::Union:
298400 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate struct or union" );
0 commit comments