diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 22 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 28 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp | 43 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h | 4 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 15 |
5 files changed, 72 insertions, 40 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 10b8255..563a753 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -35,8 +35,8 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, getContext().getLangOpts().ElideConstructors && d.isNRVOVariable(); CIRGenFunction::AutoVarEmission emission(d); - emission.IsEscapingByRef = d.isEscapingByref(); - if (emission.IsEscapingByRef) + emission.isEscapingByRef = d.isEscapingByref(); + if (emission.isEscapingByRef) cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: decl escaping by reference"); @@ -78,7 +78,7 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, alignment); } - emission.Addr = address; + emission.addr = address; setAddrOfLocalVar(&d, address); return emission; @@ -101,13 +101,13 @@ bool CIRGenFunction::isTrivialInitializer(const Expr *init) { void CIRGenFunction::emitAutoVarInit( const CIRGenFunction::AutoVarEmission &emission) { - assert(emission.Variable && "emission was not valid!"); + assert(emission.variable && "emission was not valid!"); // If this was emitted as a global constant, we're done. if (emission.wasEmittedAsGlobal()) return; - const VarDecl &d = *emission.Variable; + const VarDecl &d = *emission.variable; QualType type = d.getType(); @@ -124,7 +124,7 @@ void CIRGenFunction::emitAutoVarInit( return; } - const Address addr = emission.Addr; + const Address addr = emission.addr; // Check whether this is a byref variable that's potentially // captured and moved by its own initializer. If so, we'll need to @@ -153,7 +153,7 @@ void CIRGenFunction::emitAutoVarInit( } mlir::Attribute constant; - if (emission.IsConstantAggregate || + if (emission.isConstantAggregate || d.mightBeUsableInConstantExpressions(getContext())) { // FIXME: Differently from LLVM we try not to emit / lower too much // here for CIR since we are interested in seeing the ctor in some @@ -196,7 +196,7 @@ void CIRGenFunction::emitAutoVarInit( // FIXME(cir): migrate most of this file to use mlir::TypedAttr directly. auto typedConstant = mlir::dyn_cast<mlir::TypedAttr>(constant); assert(typedConstant && "expected typed attribute"); - if (!emission.IsConstantAggregate) { + if (!emission.isConstantAggregate) { // For simple scalar/complex initialization, store the value directly. LValue lv = makeAddrLValue(addr, type); assert(init && "expected initializer"); @@ -209,7 +209,7 @@ void CIRGenFunction::emitAutoVarInit( void CIRGenFunction::emitAutoVarCleanups( const CIRGenFunction::AutoVarEmission &emission) { - const VarDecl &d = *emission.Variable; + const VarDecl &d = *emission.variable; // Check the type for a cleanup. if (QualType::DestructionKind dtorKind = d.needsDestruction(getContext())) @@ -821,7 +821,7 @@ void CIRGenFunction::emitAutoVarTypeCleanup( // original stack object, not the possibly forwarded object. Address addr = emission.getObjectAddress(*this); - const VarDecl *var = emission.Variable; + const VarDecl *var = emission.variable; QualType type = var->getType(); CleanupKind cleanupKind = NormalAndEHCleanup; @@ -834,7 +834,7 @@ void CIRGenFunction::emitAutoVarTypeCleanup( case QualType::DK_cxx_destructor: // If there's an NRVO flag on the emission, we need a different // cleanup. - if (emission.NRVOFlag) { + if (emission.nrvoFlag) { cgm.errorNYI(var->getSourceRange(), "emitAutoVarTypeCleanup: NRVO"); return; } diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index c0ed8b4..cb7cf98 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -479,55 +479,55 @@ public: ConstantEmission tryEmitAsConstant(const MemberExpr *me); struct AutoVarEmission { - const clang::VarDecl *Variable; + const clang::VarDecl *variable; /// The address of the alloca for languages with explicit address space /// (e.g. OpenCL) or alloca casted to generic pointer for address space /// agnostic languages (e.g. C++). Invalid if the variable was emitted /// as a global constant. - Address Addr; + Address addr; /// True if the variable is of aggregate type and has a constant /// initializer. - bool IsConstantAggregate = false; + bool isConstantAggregate = false; /// True if the variable is a __block variable that is captured by an /// escaping block. - bool IsEscapingByRef = false; + bool isEscapingByRef = false; /// True if the variable was emitted as an offload recipe, and thus doesn't /// have the same sort of alloca initialization. - bool EmittedAsOffload = false; + bool emittedAsOffload = false; - mlir::Value NRVOFlag{}; + mlir::Value nrvoFlag{}; struct Invalid {}; - AutoVarEmission(Invalid) : Variable(nullptr), Addr(Address::invalid()) {} + AutoVarEmission(Invalid) : variable(nullptr), addr(Address::invalid()) {} AutoVarEmission(const clang::VarDecl &variable) - : Variable(&variable), Addr(Address::invalid()) {} + : variable(&variable), addr(Address::invalid()) {} static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); } - bool wasEmittedAsGlobal() const { return !Addr.isValid(); } + bool wasEmittedAsGlobal() const { return !addr.isValid(); } - bool wasEmittedAsOffloadClause() const { return EmittedAsOffload; } + bool wasEmittedAsOffloadClause() const { return emittedAsOffload; } /// Returns the raw, allocated address, which is not necessarily /// the address of the object itself. It is casted to default /// address space for address space agnostic languages. - Address getAllocatedAddress() const { return Addr; } + Address getAllocatedAddress() const { return addr; } // Changes the stored address for the emission. This function should only // be used in extreme cases, and isn't required to model normal AST // initialization/variables. - void setAllocatedAddress(Address A) { Addr = A; } + void setAllocatedAddress(Address a) { addr = a; } /// Returns the address of the object within this declaration. /// Note that this does not chase the forwarding pointer for /// __block decls. Address getObjectAddress(CIRGenFunction &cgf) const { - if (!IsEscapingByRef) - return Addr; + if (!isEscapingByRef) + return addr; assert(!cir::MissingFeatures::opAllocaEscapeByReference()); return Address::invalid(); diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp index e603884..565030d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp @@ -400,6 +400,32 @@ void OpenACCRecipeBuilderBase::createRecipeDestroySection( mlir::acc::YieldOp::create(builder, locEnd); } +void OpenACCRecipeBuilderBase::makeBoundsInit( + mlir::Value alloca, mlir::Location loc, mlir::Block *block, + const VarDecl *allocaDecl, QualType origType, bool isInitSection) { + mlir::OpBuilder::InsertionGuard guardCase(builder); + builder.setInsertionPointToEnd(block); + CIRGenFunction::LexicalScope ls(cgf, loc, block); + + CIRGenFunction::AutoVarEmission tempDeclEmission{*allocaDecl}; + tempDeclEmission.emittedAsOffload = true; + + // The init section is the only one of the handful that only has a single + // argument for the 'type', so we have to drop 1 for init, and future calls + // to this will need to drop 2. + llvm::MutableArrayRef<mlir::BlockArgument> boundsRange = + block->getArguments().drop_front(isInitSection ? 1 : 2); + + mlir::Value subscriptedValue = alloca; + for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange)) + subscriptedValue = createBoundsLoop(subscriptedValue, boundArg, loc, + /*inverse=*/false); + + tempDeclEmission.setAllocatedAddress( + Address{subscriptedValue, cgf.convertType(origType), + cgf.getContext().getDeclAlign(allocaDecl)}); + cgf.emitAutoVarInit(tempDeclEmission); +} // TODO: OpenACC: When we get this implemented for the reduction/firstprivate, // this might end up re-merging with createRecipeInitCopy. For now, keep it @@ -442,11 +468,16 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe( cgf.emitAutoVarAlloca(*allocaDecl, builder.saveInsertionPoint()); cgf.emitAutoVarInit(tempDeclEmission); } else { - makeBoundsAlloca(block, exprRange, loc, "openacc.private.init", numBounds, - boundTypes); - - if (initExpr) - cgf.cgm.errorNYI(exprRange, "private-init with bounds initialization"); + mlir::Value alloca = makeBoundsAlloca( + block, exprRange, loc, "openacc.private.init", numBounds, boundTypes); + + // If the initializer is trivial, there is nothing to do here, so save + // ourselves some effort. + if (initExpr && (!cgf.isTrivialInitializer(initExpr) || + cgf.getContext().getLangOpts().getTrivialAutoVarInit() != + LangOptions::TrivialAutoVarInitKind::Uninitialized)) + makeBoundsInit(alloca, loc, block, allocaDecl, origType, + /*isInitSection=*/true); } mlir::acc::YieldOp::create(builder, locEnd); @@ -473,7 +504,7 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy( // that instead of the variable in the other block. tempDeclEmission.setAllocatedAddress( Address{toArg, elementTy, cgf.getContext().getDeclAlign(varRecipe)}); - tempDeclEmission.EmittedAsOffload = true; + tempDeclEmission.emittedAsOffload = true; CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, temporary}; cgf.setAddrOfLocalVar( diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h index d802ccb..203eaff 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h @@ -35,6 +35,10 @@ class OpenACCRecipeBuilderBase { size_t numBounds, llvm::ArrayRef<QualType> boundTypes); + void makeBoundsInit(mlir::Value alloca, mlir::Location loc, + mlir::Block *block, const VarDecl *allocaDecl, + QualType origType, bool isInitSection); + protected: CIRGen::CIRGenFunction &cgf; CIRGen::CIRGenBuilderTy &builder; diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 2baeb43..87f2340 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -296,9 +296,8 @@ void CIRRecordLowering::lower(bool nonVirtualBaseType) { } llvm::stable_sort(members); - // TODO: implement clipTailPadding once bitfields are implemented - assert(!cir::MissingFeatures::bitfields()); - assert(!cir::MissingFeatures::recordZeroInit()); + // TODO: Verify bitfield clipping + assert(!cir::MissingFeatures::checkBitfieldClipping()); members.push_back(makeStorageInfo(size, getUIntNType(8))); determinePacked(nonVirtualBaseType); @@ -319,9 +318,11 @@ void CIRRecordLowering::fillOutputFields() { fieldIdxMap[member.fieldDecl->getCanonicalDecl()] = fieldTypes.size() - 1; // A field without storage must be a bitfield. - assert(!cir::MissingFeatures::bitfields()); - if (!member.data) + if (!member.data) { + assert(member.fieldDecl && + "member.data is a nullptr so member.fieldDecl should not be"); setBitFieldInfo(member.fieldDecl, member.offset, fieldTypes.back()); + } } else if (member.kind == MemberInfo::InfoKind::Base) { nonVirtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1; } else if (member.kind == MemberInfo::InfoKind::VBase) { @@ -697,13 +698,9 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) { ty ? *ty : cir::RecordType{}, baseTy ? baseTy : cir::RecordType{}, (bool)lowering.zeroInitializable, (bool)lowering.zeroInitializableAsBase); - assert(!cir::MissingFeatures::recordZeroInit()); - rl->nonVirtualBases.swap(lowering.nonVirtualBases); rl->completeObjectVirtualBases.swap(lowering.virtualBases); - assert(!cir::MissingFeatures::bitfields()); - // Add all the field numbers. rl->fieldIdxMap.swap(lowering.fieldIdxMap); |