-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CIR] Upstream global initialization for ArrayType #131657
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
Changes from all commits
4ae9c42
ea0aee4
9cbe2e4
27eaf94
4c97120
978303c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -158,13 +158,63 @@ class ConstExprEmitter | |
|
||
// TODO(cir): this can be shared with LLVM's codegen | ||
static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) { | ||
if (auto at = type->getAs<AtomicType>()) { | ||
if (const auto *at = type->getAs<AtomicType>()) { | ||
return cgm.getASTContext().getQualifiedType(at->getValueType(), | ||
type.getQualifiers()); | ||
} | ||
return type; | ||
} | ||
|
||
static mlir::Attribute | ||
emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, | ||
mlir::Type commonElementType, unsigned arrayBound, | ||
SmallVectorImpl<mlir::TypedAttr> &elements, | ||
mlir::TypedAttr filler) { | ||
const CIRGenBuilderTy &builder = cgm.getBuilder(); | ||
|
||
unsigned nonzeroLength = arrayBound; | ||
if (elements.size() < nonzeroLength && builder.isNullValue(filler)) | ||
nonzeroLength = elements.size(); | ||
|
||
if (nonzeroLength == elements.size()) { | ||
while (nonzeroLength > 0 && | ||
builder.isNullValue(elements[nonzeroLength - 1])) | ||
--nonzeroLength; | ||
} | ||
|
||
if (nonzeroLength == 0) | ||
return cir::ZeroAttr::get(builder.getContext(), desiredType); | ||
|
||
const unsigned trailingZeroes = arrayBound - nonzeroLength; | ||
|
||
// Add a zeroinitializer array filler if we have lots of trailing zeroes. | ||
if (trailingZeroes >= 8) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You've dropped a comment from the incubator code here that explains the purpose of the comparison with 8 -- "if we have lots of trailing zeroes". Without the comment, 8 is purely a magic number with no context. |
||
assert(elements.size() >= nonzeroLength && | ||
"missing initializer for non-zero element"); | ||
} else if (elements.size() != arrayBound) { | ||
elements.resize(arrayBound, filler); | ||
|
||
if (filler.getType() != commonElementType) | ||
commonElementType = {}; | ||
} | ||
|
||
if (commonElementType) { | ||
SmallVector<mlir::Attribute, 4> eles; | ||
eles.reserve(elements.size()); | ||
|
||
for (const auto &element : elements) | ||
eles.push_back(element); | ||
|
||
return cir::ConstArrayAttr::get( | ||
cir::ArrayType::get(builder.getContext(), commonElementType, | ||
arrayBound), | ||
mlir::ArrayAttr::get(builder.getContext(), eles)); | ||
} | ||
|
||
cgm.errorNYI("array with different type elements"); | ||
return {}; | ||
} | ||
|
||
//===----------------------------------------------------------------------===// | ||
// ConstantEmitter | ||
//===----------------------------------------------------------------------===// | ||
|
@@ -271,16 +321,57 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, | |
cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) { | ||
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half"); | ||
return {}; | ||
} else { | ||
mlir::Type ty = cgm.convertType(destType); | ||
assert(mlir::isa<cir::CIRFPTypeInterface>(ty) && | ||
"expected floating-point type"); | ||
return cgm.getBuilder().getAttr<cir::FPAttr>(ty, init); | ||
} | ||
|
||
mlir::Type ty = cgm.convertType(destType); | ||
assert(mlir::isa<cir::CIRFPTypeInterface>(ty) && | ||
"expected floating-point type"); | ||
return cgm.getBuilder().getAttr<cir::FPAttr>(ty, init); | ||
} | ||
case APValue::Array: { | ||
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate array"); | ||
return {}; | ||
const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType); | ||
const QualType arrayElementTy = arrayTy->getElementType(); | ||
const unsigned numElements = value.getArraySize(); | ||
const unsigned numInitElts = value.getArrayInitializedElts(); | ||
|
||
mlir::Attribute filler; | ||
if (value.hasArrayFiller()) { | ||
filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy); | ||
if (!filler) | ||
return {}; | ||
} | ||
|
||
SmallVector<mlir::TypedAttr, 16> elements; | ||
if (filler && builder.isNullValue(filler)) | ||
elements.reserve(numInitElts + 1); | ||
else | ||
elements.reserve(numInitElts); | ||
|
||
mlir::Type commonElementType; | ||
for (unsigned i = 0; i < numInitElts; ++i) { | ||
const APValue &arrayElement = value.getArrayInitializedElt(i); | ||
const mlir::Attribute element = | ||
tryEmitPrivateForMemory(arrayElement, arrayElementTy); | ||
if (!element) | ||
return {}; | ||
|
||
const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element); | ||
if (i == 0) | ||
commonElementType = elementTyped.getType(); | ||
else if (elementTyped.getType() != commonElementType) { | ||
commonElementType = {}; | ||
} | ||
|
||
elements.push_back(elementTyped); | ||
} | ||
|
||
mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler); | ||
if (filler && !typedFiller) | ||
cgm.errorNYI("array filler should always be typed"); | ||
|
||
mlir::Type desiredType = cgm.convertType(destType); | ||
return emitArrayConstant(cgm, desiredType, commonElementType, numElements, | ||
elements, typedFiller); | ||
} | ||
case APValue::Vector: { | ||
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate vector"); | ||
|
@@ -290,9 +381,23 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, | |
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer"); | ||
return {}; | ||
} | ||
case APValue::LValue: | ||
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate lvalue"); | ||
case APValue::LValue: { | ||
|
||
if (value.getLValueBase()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're probably going to want to leave ConstantLValueEmitter::tryEmit() as a separate function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, i think later we need to upstreaming ConstantLValueEmitter and also implement the visitors |
||
cgm.errorNYI("non-null pointer initialization"); | ||
} else { | ||
|
||
mlir::Type desiredType = cgm.convertType(destType); | ||
if (const cir::PointerType ptrType = | ||
mlir::dyn_cast<cir::PointerType>(desiredType)) { | ||
return builder.getConstPtrAttr(ptrType, | ||
value.getLValueOffset().getQuantity()); | ||
} else { | ||
llvm_unreachable("non-pointer variable initialized with a pointer"); | ||
} | ||
} | ||
return {}; | ||
} | ||
case APValue::Struct: | ||
case APValue::Union: | ||
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful to have a comment here explaining the intent of this function. In particular, some clarification is necessary as to what it means for an FPAtt. The function returns false for -0.0, which means it is not simply testing for equality with zero.