diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenBuilder.h | 30 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 26 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp | 32 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 5 |
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) |