Skip to content

Commit

Permalink
[CIR][CIRGen][NFC] More skeleton for building constants
Browse files Browse the repository at this point in the history
  • Loading branch information
bcardosolopes committed Oct 19, 2024
1 parent cb0cb34 commit c1731b1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 7 deletions.
19 changes: 18 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,24 @@ static void buildNullBaseClassInitialization(CIRGenFunction &CGF,
Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
}

llvm_unreachable("NYI");
// If the type contains a pointer to data member we can't memset it to zero.
// Instead, create a null constant and copy it to the destination.
// TODO: there are other patterns besides zero that we can usefully memset,
// like -1, which happens to be the pattern used by member-pointers.
// TODO: isZeroInitializable can be over-conservative in the case where a
// virtual base contains a member pointer.
// TODO(cir): `nullConstantForBase` might be better off as a value instead
// of an mlir::TypedAttr? Once this moves out of skeleton, make sure to double
// check on what's better.
mlir::Attribute nullConstantForBase = CGF.CGM.buildNullConstantForBase(Base);
if (!CGF.getBuilder().isNullValue(nullConstantForBase)) {
llvm_unreachable("NYI");
// Otherwise, just memset the whole thing to zero. This is legal
// because in LLVM, all default initializers (other than the ones we just
// handled above) are guaranteed to have a bit pattern of all zeros.
} else {
llvm_unreachable("NYI");
}
}

void CIRGenFunction::buildCXXConstructExpr(const CXXConstructExpr *E,
Expand Down
68 changes: 63 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenExprConst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1958,13 +1958,71 @@ mlir::Attribute ConstantEmitter::emitNullForMemory(mlir::Location loc,
return emitForMemory(CGM, cstOp.getValue(), T);
}

static mlir::Value buildNullConstant(CIRGenModule &CGM,
const RecordDecl *record,
bool asCompleteObject) {
llvm_unreachable("NYI");
static mlir::TypedAttr buildNullConstant(CIRGenModule &CGM,
const RecordDecl *record,
bool asCompleteObject) {
const CIRGenRecordLayout &layout =
CGM.getTypes().getCIRGenRecordLayout(record);
mlir::Type ty = (asCompleteObject ? layout.getCIRType()
: layout.getBaseSubobjectCIRType());
auto structure = dyn_cast<mlir::cir::StructType>(ty);
assert(structure && "expected");

unsigned numElements = structure.getNumElements();
SmallVector<mlir::Attribute, 4> elements(numElements);

auto CXXR = dyn_cast<CXXRecordDecl>(record);
// Fill in all the bases.
if (CXXR) {
for (const auto &I : CXXR->bases()) {
if (I.isVirtual()) {
// Ignore virtual bases; if we're laying out for a complete
// object, we'll lay these out later.
continue;
}
llvm_unreachable("NYI");
}
}

// Fill in all the fields.
for (const auto *Field : record->fields()) {
// Fill in non-bitfields. (Bitfields always use a zero pattern, which we
// will fill in later.)
if (!Field->isBitField()) {
// TODO(cir) check for !isEmptyFieldForLayout(CGM.getContext(), Field))
llvm_unreachable("NYI");
}

// For unions, stop after the first named field.
if (record->isUnion()) {
if (Field->getIdentifier())
break;
if (const auto *FieldRD = Field->getType()->getAsRecordDecl())
if (FieldRD->findFirstNamedDataMember())
break;
}
}

// Fill in the virtual bases, if we're working with the complete object.
if (CXXR && asCompleteObject) {
for ([[maybe_unused]] const auto &I : CXXR->vbases()) {
llvm_unreachable("NYI");
}
}

// Now go through all other fields and zero them out.
for (unsigned i = 0; i != numElements; ++i) {
if (!elements[i]) {
llvm_unreachable("NYI");
}
}

mlir::MLIRContext *mlirCtx = structure.getContext();
return mlir::cir::ConstStructAttr::get(
mlirCtx, structure, mlir::ArrayAttr::get(mlirCtx, elements));
}

mlir::Value
mlir::TypedAttr
CIRGenModule::buildNullConstantForBase(const CXXRecordDecl *Record) {
return ::buildNullConstant(*this, Record, false);
}
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ class CIRGenModule : public CIRGenTypeCache {

/// Return a null constant appropriate for zero-initializing a base class with
/// the given type. This is usually, but not always, an LLVM null constant.
mlir::Value buildNullConstantForBase(const CXXRecordDecl *Record);
mlir::TypedAttr buildNullConstantForBase(const CXXRecordDecl *Record);

mlir::Value buildMemberPointerConstant(const UnaryOperator *E);

Expand Down

0 comments on commit c1731b1

Please sign in to comment.