aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuilder.h30
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp26
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp6
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp32
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp5
5 files changed, 62 insertions, 37 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 73c9fb9..ff8e121 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -410,21 +410,37 @@ public:
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
Address dstAddr, mlir::Type storageType,
mlir::Value src, const CIRGenBitFieldInfo &info,
- bool isLvalueVolatile) {
+ bool isLvalueVolatile, bool useVolatile) {
+ unsigned offset = useVolatile ? info.volatileOffset : info.offset;
+
+ // If using AAPCS and the field is volatile, load with the size of the
+ // declared field
+ storageType =
+ useVolatile ? cir::IntType::get(storageType.getContext(),
+ info.volatileStorageSize, info.isSigned)
+ : storageType;
return create<cir::SetBitfieldOp>(
loc, resultType, dstAddr.getPointer(), storageType, src, info.name,
- info.size, info.offset, info.isSigned, isLvalueVolatile,
+ info.size, offset, info.isSigned, isLvalueVolatile,
dstAddr.getAlignment().getAsAlign().value());
}
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType,
Address addr, mlir::Type storageType,
const CIRGenBitFieldInfo &info,
- bool isLvalueVolatile) {
- return create<cir::GetBitfieldOp>(
- loc, resultType, addr.getPointer(), storageType, info.name, info.size,
- info.offset, info.isSigned, isLvalueVolatile,
- addr.getAlignment().getAsAlign().value());
+ bool isLvalueVolatile, bool useVolatile) {
+ unsigned offset = useVolatile ? info.volatileOffset : info.offset;
+
+ // If using AAPCS and the field is volatile, load with the size of the
+ // declared field
+ storageType =
+ useVolatile ? cir::IntType::get(storageType.getContext(),
+ info.volatileStorageSize, info.isSigned)
+ : storageType;
+ return create<cir::GetBitfieldOp>(loc, resultType, addr.getPointer(),
+ storageType, info.name, info.size, offset,
+ info.isSigned, isLvalueVolatile,
+ addr.getAlignment().getAsAlign().value());
}
};
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index cd37a2b..8ae63bf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -322,22 +322,28 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
assert(!cir::MissingFeatures::opTBAA());
}
+// TODO: Replace this with a proper TargetInfo function call.
+/// Helper method to check if the underlying ABI is AAPCS
+static bool isAAPCS(const TargetInfo &targetInfo) {
+ return targetInfo.getABI().starts_with("aapcs");
+}
+
mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
LValue dst) {
- assert(!cir::MissingFeatures::armComputeVolatileBitfields());
-
const CIRGenBitFieldInfo &info = dst.getBitFieldInfo();
mlir::Type resLTy = convertTypeForMem(dst.getType());
Address ptr = dst.getBitFieldAddress();
- assert(!cir::MissingFeatures::armComputeVolatileBitfields());
+ bool useVoaltile = cgm.getCodeGenOpts().AAPCSBitfieldWidth &&
+ dst.isVolatileQualified() &&
+ info.volatileStorageSize != 0 && isAAPCS(cgm.getTarget());
mlir::Value dstAddr = dst.getAddress().getPointer();
return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr,
ptr.getElementType(), src.getValue(), info,
- dst.isVolatileQualified());
+ dst.isVolatileQualified(), useVoaltile);
}
RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
@@ -347,10 +353,12 @@ RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
mlir::Type resLTy = convertType(lv.getType());
Address ptr = lv.getBitFieldAddress();
- assert(!cir::MissingFeatures::armComputeVolatileBitfields());
+ bool useVoaltile = lv.isVolatileQualified() && info.volatileOffset != 0 &&
+ isAAPCS(cgm.getTarget());
- mlir::Value field = builder.createGetBitfield(
- getLoc(loc), resLTy, ptr, ptr.getElementType(), info, lv.isVolatile());
+ mlir::Value field =
+ builder.createGetBitfield(getLoc(loc), resLTy, ptr, ptr.getElementType(),
+ info, lv.isVolatile(), useVoaltile);
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI");
return RValue::get(field);
}
@@ -375,10 +383,10 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
const CIRGenRecordLayout &layout =
cgm.getTypes().getCIRGenRecordLayout(field->getParent());
const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
- assert(!cir::MissingFeatures::armComputeVolatileBitfields());
+
assert(!cir::MissingFeatures::preservedAccessIndexRegion());
- unsigned idx = layout.getCIRFieldNo(field);
+ unsigned idx = layout.getCIRFieldNo(field);
Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);
mlir::Location loc = getLoc(field->getLocation());
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
index 32095cb..907cb5f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
@@ -119,7 +119,8 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))
return {exprLoc, emitMemberExpr(memExpr).getPointer(), exprString,
- curVarExpr->getType(), std::move(bounds)};
+ curVarExpr->getType().getNonReferenceType().getUnqualifiedType(),
+ std::move(bounds)};
// Sema has made sure that only 4 types of things can get here, array
// subscript, array section, member expr, or DRE to a var decl (or the
@@ -127,5 +128,6 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
// right.
const auto *dre = cast<DeclRefExpr>(curVarExpr);
return {exprLoc, emitDeclRefLValue(dre).getPointer(), exprString,
- curVarExpr->getType(), std::move(bounds)};
+ curVarExpr->getType().getNonReferenceType().getUnqualifiedType(),
+ std::move(bounds)};
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index 5a6e665..bb9054a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -358,8 +358,8 @@ class OpenACCClauseCIREmitter final
template <typename RecipeTy>
RecipeTy getOrCreateRecipe(ASTContext &astCtx, const Expr *varRef,
- DeclContext *dc, QualType baseType,
- mlir::Value mainOp) {
+ const VarDecl *varRecipe, DeclContext *dc,
+ QualType baseType, mlir::Value mainOp) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
@@ -398,12 +398,6 @@ class OpenACCClauseCIREmitter final
auto recipe =
RecipeTy::create(modBuilder, loc, recipeName, mainOp.getType());
- // Magic-up a var-decl so we can use normal init/destruction operations for
- // a variable declaration.
- VarDecl &tempDecl = *VarDecl::Create(
- astCtx, dc, varRef->getBeginLoc(), varRef->getBeginLoc(),
- &astCtx.Idents.get("openacc.private.init"), baseType,
- astCtx.getTrivialTypeSourceInfo(baseType), SC_Auto);
CIRGenFunction::AutoVarEmission tempDeclEmission{
CIRGenFunction::AutoVarEmission::invalid()};
@@ -422,9 +416,11 @@ class OpenACCClauseCIREmitter final
"OpenACC non-private recipe init");
}
- tempDeclEmission =
- cgf.emitAutoVarAlloca(tempDecl, builder.saveInsertionPoint());
- cgf.emitAutoVarInit(tempDeclEmission);
+ if (varRecipe) {
+ tempDeclEmission =
+ cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint());
+ cgf.emitAutoVarInit(tempDeclEmission);
+ }
mlir::acc::YieldOp::create(builder, locEnd);
}
@@ -439,7 +435,7 @@ class OpenACCClauseCIREmitter final
}
// Destroy section (doesn't currently exist).
- if (tempDecl.needsDestruction(cgf.getContext())) {
+ if (varRecipe && varRecipe->needsDestruction(cgf.getContext())) {
llvm::SmallVector<mlir::Type> argsTys{mainOp.getType()};
llvm::SmallVector<mlir::Location> argsLocs{loc};
mlir::Block *block = builder.createBlock(&recipe.getDestroyRegion(),
@@ -450,7 +446,7 @@ class OpenACCClauseCIREmitter final
mlir::Type elementTy =
mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();
Address addr{block->getArgument(0), elementTy,
- cgf.getContext().getDeclAlign(&tempDecl)};
+ cgf.getContext().getDeclAlign(varRecipe)};
cgf.emitDestroy(addr, baseType,
cgf.getDestroyer(QualType::DK_cxx_destructor));
@@ -1080,9 +1076,10 @@ public:
void VisitPrivateClause(const OpenACCPrivateClause &clause) {
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
mlir::acc::LoopOp>) {
- for (const Expr *var : clause.getVarList()) {
+ for (const auto [varExpr, varRecipe] :
+ llvm::zip_equal(clause.getVarList(), clause.getInitRecipes())) {
CIRGenFunction::OpenACCDataOperandInfo opInfo =
- cgf.getOpenACCDataOperandInfo(var);
+ cgf.getOpenACCDataOperandInfo(varExpr);
auto privateOp = mlir::acc::PrivateOp::create(
builder, opInfo.beginLoc, opInfo.varValue, /*structured=*/true,
/*implicit=*/false, opInfo.name, opInfo.bounds);
@@ -1091,8 +1088,9 @@ public:
{
mlir::OpBuilder::InsertionGuard guardCase(builder);
auto recipe = getOrCreateRecipe<mlir::acc::PrivateRecipeOp>(
- cgf.getContext(), var, Decl::castToDeclContext(cgf.curFuncDecl),
- opInfo.baseType, privateOp.getResult());
+ cgf.getContext(), varExpr, varRecipe,
+ Decl::castToDeclContext(cgf.curFuncDecl), opInfo.baseType,
+ privateOp.getResult());
// TODO: OpenACC: The dialect is going to change in the near future to
// have these be on a different operation, so when that changes, we
// probably need to change these here.
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index ecf31a7..1764967 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -847,8 +847,9 @@ void CIRRecordLowering::computeVolatileBitfields() {
const CharUnits fEnd =
fOffset +
- astContext.toCharUnitsFromBits(astContext.toBits(
- getSizeInBits(cirGenTypes.convertTypeForMem(f->getType())))) -
+ astContext.toCharUnitsFromBits(
+ getSizeInBits(cirGenTypes.convertTypeForMem(f->getType()))
+ .getQuantity()) -
CharUnits::One();
// If no overlap, continue.
if (end < fOffset || fEnd < storageOffset)