diff options
Diffstat (limited to 'flang/lib/Lower')
-rw-r--r-- | flang/lib/Lower/Bridge.cpp | 20 | ||||
-rw-r--r-- | flang/lib/Lower/ConvertVariable.cpp | 2 | ||||
-rw-r--r-- | flang/lib/Lower/OpenACC.cpp | 284 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 56 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/ClauseProcessor.h | 3 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/Clauses.cpp | 2 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/OpenMP.cpp | 101 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/Utils.cpp | 19 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/Utils.h | 2 |
9 files changed, 319 insertions, 170 deletions
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 3b711cc..a516a44 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1766,7 +1766,7 @@ private: // to a crash due to a block with no terminator. See issue #126452. mlir::FunctionType funcType = builder->getFunction().getFunctionType(); mlir::Type resultType = funcType.getResult(0); - mlir::Value undefResult = builder->create<fir::UndefOp>(loc, resultType); + mlir::Value undefResult = fir::UndefOp::create(*builder, loc, resultType); genExitRoutine(false, undefResult); return; } @@ -4010,8 +4010,8 @@ private: // parameters and dynamic type. The selector cannot be a // POINTER/ALLOCATBLE as per F'2023 C1160. fir::ExtendedValue newExv; - llvm::SmallVector assumeSizeExtents{ - builder->createMinusOneInteger(loc, builder->getIndexType())}; + llvm::SmallVector<mlir::Value> assumeSizeExtents{ + fir::AssumedSizeExtentOp::create(*builder, loc)}; mlir::Value baseAddr = hlfir::genVariableRawAddress(loc, *builder, selector); const bool isVolatile = fir::isa_volatile_type(selector.getType()); @@ -4733,11 +4733,21 @@ private: return fir::factory::createUnallocatedBox(*builder, loc, lhsBoxType, {}); hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR( loc, *this, assign.rhs, localSymbols, rhsContext); + auto rhsBoxType = rhs.getBoxType(); // Create pointer descriptor value from the RHS. if (rhs.isMutableBox()) rhs = hlfir::Entity{fir::LoadOp::create(*builder, loc, rhs)}; - mlir::Value rhsBox = hlfir::genVariableBox( - loc, *builder, rhs, lhsBoxType.getBoxTypeWithNewShape(rhs.getRank())); + + // Use LHS type if LHS is not polymorphic. + fir::BaseBoxType targetBoxType; + if (assign.lhs.GetType()->IsPolymorphic()) + targetBoxType = rhsBoxType.getBoxTypeWithNewAttr( + fir::BaseBoxType::Attribute::Pointer); + else + targetBoxType = lhsBoxType.getBoxTypeWithNewShape(rhs.getRank()); + mlir::Value rhsBox = + hlfir::genVariableBox(loc, *builder, rhs, targetBoxType); + // Apply lower bounds or reshaping if any. if (const auto *lbExprs = std::get_if<Fortran::evaluate::Assignment::BoundsSpec>(&assign.u); diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 00ec1b5..2517ab3 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -1711,7 +1711,7 @@ static void lowerExplicitLowerBounds( /// CFI_desc_t requirements in 18.5.3 point 5.). static mlir::Value getAssumedSizeExtent(mlir::Location loc, fir::FirOpBuilder &builder) { - return builder.createMinusOneInteger(loc, builder.getIndexType()); + return fir::AssumedSizeExtentOp::create(builder, loc); } /// Lower explicit extents into \p result if this is an explicit-shape or diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index b3e8b69..1fc59c7 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -718,6 +718,84 @@ static void genDataOperandOperations( } } +template <typename GlobalCtorOrDtorOp, typename EntryOp, typename DeclareOp, + typename ExitOp> +static void createDeclareGlobalOp(mlir::OpBuilder &modBuilder, + fir::FirOpBuilder &builder, + mlir::Location loc, fir::GlobalOp globalOp, + mlir::acc::DataClause clause, + const std::string &declareGlobalName, + bool implicit, std::stringstream &asFortran) { + GlobalCtorOrDtorOp declareGlobalOp = + GlobalCtorOrDtorOp::create(modBuilder, loc, declareGlobalName); + builder.createBlock(&declareGlobalOp.getRegion(), + declareGlobalOp.getRegion().end(), {}, {}); + builder.setInsertionPointToEnd(&declareGlobalOp.getRegion().back()); + + fir::AddrOfOp addrOp = fir::AddrOfOp::create( + builder, loc, fir::ReferenceType::get(globalOp.getType()), + globalOp.getSymbol()); + addDeclareAttr(builder, addrOp, clause); + + llvm::SmallVector<mlir::Value> bounds; + EntryOp entryOp = createDataEntryOp<EntryOp>( + builder, loc, addrOp.getResTy(), asFortran, bounds, + /*structured=*/false, implicit, clause, addrOp.getResTy().getType(), + /*async=*/{}, /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{}); + if constexpr (std::is_same_v<DeclareOp, mlir::acc::DeclareEnterOp>) + DeclareOp::create(builder, loc, + mlir::acc::DeclareTokenType::get(entryOp.getContext()), + mlir::ValueRange(entryOp.getAccVar())); + else + DeclareOp::create(builder, loc, mlir::Value{}, + mlir::ValueRange(entryOp.getAccVar())); + if constexpr (std::is_same_v<GlobalCtorOrDtorOp, + mlir::acc::GlobalDestructorOp>) { + if constexpr (std::is_same_v<ExitOp, mlir::acc::DeclareLinkOp>) { + // No destructor emission for declare link in this path to avoid + // complex var/varType/varPtrPtr signatures. The ctor registers the link. + } else if constexpr (std::is_same_v<ExitOp, mlir::acc::CopyoutOp> || + std::is_same_v<ExitOp, mlir::acc::UpdateHostOp>) { + ExitOp::create(builder, entryOp.getLoc(), entryOp.getAccVar(), + entryOp.getVar(), entryOp.getVarType(), + entryOp.getBounds(), entryOp.getAsyncOperands(), + entryOp.getAsyncOperandsDeviceTypeAttr(), + entryOp.getAsyncOnlyAttr(), entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); + } else { + ExitOp::create(builder, entryOp.getLoc(), entryOp.getAccVar(), + entryOp.getBounds(), entryOp.getAsyncOperands(), + entryOp.getAsyncOperandsDeviceTypeAttr(), + entryOp.getAsyncOnlyAttr(), entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); + } + } + mlir::acc::TerminatorOp::create(builder, loc); + modBuilder.setInsertionPointAfter(declareGlobalOp); +} + +template <typename EntryOp, typename ExitOp> +static void +emitCtorDtorPair(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, + mlir::Location operandLocation, fir::GlobalOp globalOp, + mlir::acc::DataClause clause, std::stringstream &asFortran, + const std::string &ctorName) { + createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp, + mlir::acc::DeclareEnterOp, ExitOp>( + modBuilder, builder, operandLocation, globalOp, clause, ctorName, + /*implicit=*/false, asFortran); + + std::stringstream dtorName; + dtorName << globalOp.getSymName().str() << "_acc_dtor"; + createDeclareGlobalOp<mlir::acc::GlobalDestructorOp, + mlir::acc::GetDevicePtrOp, mlir::acc::DeclareExitOp, + ExitOp>(modBuilder, builder, operandLocation, globalOp, + clause, dtorName.str(), + /*implicit=*/false, asFortran); +} + template <typename EntryOp, typename ExitOp> static void genDeclareDataOperandOperations( const Fortran::parser::AccObjectList &objectList, @@ -733,6 +811,37 @@ static void genDeclareDataOperandOperations( std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject); + // Handle COMMON/global symbols via module-level ctor/dtor path. + if (symbol.detailsIf<Fortran::semantics::CommonBlockDetails>() || + Fortran::semantics::FindCommonBlockContaining(symbol)) { + emitCommonGlobal( + converter, builder, accObject, dataClause, + [&](mlir::OpBuilder &modBuilder, mlir::Location loc, + fir::GlobalOp globalOp, mlir::acc::DataClause clause, + std::stringstream &asFortranStr, const std::string &ctorName) { + if constexpr (std::is_same_v<EntryOp, mlir::acc::DeclareLinkOp>) { + createDeclareGlobalOp< + mlir::acc::GlobalConstructorOp, mlir::acc::DeclareLinkOp, + mlir::acc::DeclareEnterOp, mlir::acc::DeclareLinkOp>( + modBuilder, builder, loc, globalOp, clause, ctorName, + /*implicit=*/false, asFortranStr); + } else if constexpr (std::is_same_v<EntryOp, mlir::acc::CreateOp> || + std::is_same_v<EntryOp, mlir::acc::CopyinOp> || + std::is_same_v< + EntryOp, + mlir::acc::DeclareDeviceResidentOp> || + std::is_same_v<ExitOp, mlir::acc::CopyoutOp>) { + emitCtorDtorPair<EntryOp, ExitOp>(modBuilder, builder, loc, + globalOp, clause, asFortranStr, + ctorName); + } else { + // No module-level ctor/dtor for this clause (e.g., deviceptr, + // present). Handled via structured declare region only. + return; + } + }); + continue; + } Fortran::semantics::MaybeExpr designator = Fortran::common::visit( [&](auto &&s) { return ea.Analyze(s); }, accObject.u); fir::factory::AddrAndBoundsInfo info = @@ -2257,6 +2366,23 @@ static void processDoLoopBounds( } } +static void remapCommonBlockMember( + Fortran::lower::AbstractConverter &converter, mlir::Location loc, + const Fortran::semantics::Symbol &member, + mlir::Value newCommonBlockBaseAddress, + const Fortran::semantics::Symbol &commonBlockSymbol, + llvm::SmallPtrSetImpl<const Fortran::semantics::Symbol *> &seenSymbols) { + if (seenSymbols.contains(&member)) + return; + mlir::Value accMemberValue = Fortran::lower::genCommonBlockMember( + converter, loc, member, newCommonBlockBaseAddress, + commonBlockSymbol.size()); + fir::ExtendedValue hostExv = converter.getSymbolExtendedValue(member); + fir::ExtendedValue accExv = fir::substBase(hostExv, accMemberValue); + converter.bindSymbol(member, accExv); + seenSymbols.insert(&member); +} + /// Remap symbols that appeared in OpenACC data clauses to use the results of /// the corresponding data operations. This allows isolating symbol accesses /// inside the OpenACC region from accesses in the host and other regions while @@ -2282,14 +2408,39 @@ static void remapDataOperandSymbols( builder.setInsertionPointToStart(®ionOp.getRegion().front()); llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 8> seenSymbols; mlir::IRMapping mapper; + mlir::Location loc = regionOp.getLoc(); for (auto [value, symbol] : dataOperandSymbolPairs) { - - // If A symbol appears on several data clause, just map it to the first + // If a symbol appears on several data clause, just map it to the first // result (all data operations results for a symbol are pointing same // memory, so it does not matter which one is used). if (seenSymbols.contains(&symbol.get())) continue; seenSymbols.insert(&symbol.get()); + // When a common block appears in a directive, remap its members. + // Note: this will instantiate all common block members even if they are not + // used inside the region. If hlfir.declare DCE is not made possible, this + // could be improved to reduce IR noise. + if (const auto *commonBlock = symbol->template detailsIf< + Fortran::semantics::CommonBlockDetails>()) { + const Fortran::semantics::Scope &commonScope = symbol->owner(); + if (commonScope.equivalenceSets().empty()) { + for (auto member : commonBlock->objects()) + remapCommonBlockMember(converter, loc, *member, value, *symbol, + seenSymbols); + } else { + // Objects equivalenced with common block members still belong to the + // common block storage even if they are not part of the common block + // declaration. The easiest and most robust way to find all symbols + // belonging to the common block is to loop through the scope symbols + // and check if they belong to the common. + for (const auto &scopeSymbol : commonScope) + if (Fortran::semantics::FindCommonBlockContaining( + *scopeSymbol.second) == &symbol.get()) + remapCommonBlockMember(converter, loc, *scopeSymbol.second, value, + *symbol, seenSymbols); + } + continue; + } std::optional<fir::FortranVariableOpInterface> hostDef = symbolMap.lookupVariableDefinition(symbol); assert(hostDef.has_value() && llvm::isa<hlfir::DeclareOp>(*hostDef) && @@ -2306,10 +2457,8 @@ static void remapDataOperandSymbols( "box type mismatch between compute region variable and " "hlfir.declare input unexpected"); if (Fortran::semantics::IsOptional(symbol)) - TODO(regionOp.getLoc(), - "remapping OPTIONAL symbol in OpenACC compute region"); - auto rawValue = - fir::BoxAddrOp::create(builder, regionOp.getLoc(), hostType, value); + TODO(loc, "remapping OPTIONAL symbol in OpenACC compute region"); + auto rawValue = fir::BoxAddrOp::create(builder, loc, hostType, value); mapper.map(hostInput, rawValue); } else { assert(!llvm::isa<fir::BaseBoxType>(hostType) && @@ -2321,8 +2470,7 @@ static void remapDataOperandSymbols( assert(fir::isa_ref_type(hostType) && fir::isa_ref_type(computeType) && "compute region variable and host variable should both be raw " "addresses"); - mlir::Value cast = - builder.createConvert(regionOp.getLoc(), hostType, value); + mlir::Value cast = builder.createConvert(loc, hostType, value); mapper.map(hostInput, cast); } if (mlir::Value dummyScope = hostDeclare.getDummyScope()) { @@ -4098,49 +4246,6 @@ static void genACC(Fortran::lower::AbstractConverter &converter, waitOp.setAsyncAttr(firOpBuilder.getUnitAttr()); } -template <typename GlobalOp, typename EntryOp, typename DeclareOp, - typename ExitOp> -static void createDeclareGlobalOp(mlir::OpBuilder &modBuilder, - fir::FirOpBuilder &builder, - mlir::Location loc, fir::GlobalOp globalOp, - mlir::acc::DataClause clause, - const std::string &declareGlobalName, - bool implicit, std::stringstream &asFortran) { - GlobalOp declareGlobalOp = - GlobalOp::create(modBuilder, loc, declareGlobalName); - builder.createBlock(&declareGlobalOp.getRegion(), - declareGlobalOp.getRegion().end(), {}, {}); - builder.setInsertionPointToEnd(&declareGlobalOp.getRegion().back()); - - fir::AddrOfOp addrOp = fir::AddrOfOp::create( - builder, loc, fir::ReferenceType::get(globalOp.getType()), - globalOp.getSymbol()); - addDeclareAttr(builder, addrOp, clause); - - llvm::SmallVector<mlir::Value> bounds; - EntryOp entryOp = createDataEntryOp<EntryOp>( - builder, loc, addrOp.getResTy(), asFortran, bounds, - /*structured=*/false, implicit, clause, addrOp.getResTy().getType(), - /*async=*/{}, /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{}); - if constexpr (std::is_same_v<DeclareOp, mlir::acc::DeclareEnterOp>) - DeclareOp::create(builder, loc, - mlir::acc::DeclareTokenType::get(entryOp.getContext()), - mlir::ValueRange(entryOp.getAccVar())); - else - DeclareOp::create(builder, loc, mlir::Value{}, - mlir::ValueRange(entryOp.getAccVar())); - if constexpr (std::is_same_v<GlobalOp, mlir::acc::GlobalDestructorOp>) { - ExitOp::create(builder, entryOp.getLoc(), entryOp.getAccVar(), - entryOp.getBounds(), entryOp.getAsyncOperands(), - entryOp.getAsyncOperandsDeviceTypeAttr(), - entryOp.getAsyncOnlyAttr(), entryOp.getDataClause(), - /*structured=*/false, /*implicit=*/false, - builder.getStringAttr(*entryOp.getName())); - } - mlir::acc::TerminatorOp::create(builder, loc); - modBuilder.setInsertionPointAfter(declareGlobalOp); -} - template <typename EntryOp> static void createDeclareAllocFunc(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, @@ -4317,6 +4422,66 @@ genGlobalCtorsWithModifier(Fortran::lower::AbstractConverter &converter, dataClause); } +static fir::GlobalOp +lookupGlobalBySymbolOrEquivalence(Fortran::lower::AbstractConverter &converter, + fir::FirOpBuilder &builder, + const Fortran::semantics::Symbol &sym) { + const Fortran::semantics::Symbol *commonBlock = + Fortran::semantics::FindCommonBlockContaining(sym); + std::string globalName = commonBlock ? converter.mangleName(*commonBlock) + : converter.mangleName(sym); + if (fir::GlobalOp g = builder.getNamedGlobal(globalName)) { + return g; + } + // Not found: if not a COMMON member, try equivalence members + if (!commonBlock) { + if (const Fortran::semantics::EquivalenceSet *eqSet = + Fortran::semantics::FindEquivalenceSet(sym)) { + for (const Fortran::semantics::EquivalenceObject &eqObj : *eqSet) { + std::string eqName = converter.mangleName(eqObj.symbol); + if (fir::GlobalOp g = builder.getNamedGlobal(eqName)) + return g; + } + } + } + return {}; +} + +template <typename EmitterFn> +static void emitCommonGlobal(Fortran::lower::AbstractConverter &converter, + fir::FirOpBuilder &builder, + const Fortran::parser::AccObject &obj, + mlir::acc::DataClause clause, + EmitterFn &&emitCtorDtor) { + Fortran::semantics::Symbol &sym = getSymbolFromAccObject(obj); + if (!(sym.detailsIf<Fortran::semantics::CommonBlockDetails>() || + Fortran::semantics::FindCommonBlockContaining(sym))) + return; + + fir::GlobalOp globalOp = + lookupGlobalBySymbolOrEquivalence(converter, builder, sym); + if (!globalOp) + llvm::report_fatal_error("could not retrieve global symbol"); + + std::stringstream ctorName; + ctorName << globalOp.getSymName().str() << "_acc_ctor"; + if (builder.getModule().lookupSymbol<mlir::acc::GlobalConstructorOp>( + ctorName.str())) + return; + + mlir::Location operandLocation = genOperandLocation(converter, obj); + addDeclareAttr(builder, globalOp.getOperation(), clause); + mlir::OpBuilder modBuilder(builder.getModule().getBodyRegion()); + modBuilder.setInsertionPointAfter(globalOp); + std::stringstream asFortran; + asFortran << sym.name().ToString(); + + auto savedIP = builder.saveInsertionPoint(); + emitCtorDtor(modBuilder, operandLocation, globalOp, clause, asFortran, + ctorName.str()); + builder.restoreInsertionPoint(savedIP); +} + static void genDeclareInFunction(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semanticsContext, @@ -4342,11 +4507,9 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, dataClauseOperands.end()); } else if (const auto *createClause = std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) { - const Fortran::parser::AccObjectListWithModifier &listWithModifier = - createClause->v; - const auto &accObjectList = - std::get<Fortran::parser::AccObjectList>(listWithModifier.t); auto crtDataStart = dataClauseOperands.size(); + const auto &accObjectList = + std::get<Fortran::parser::AccObjectList>(createClause->v.t); genDeclareDataOperandOperations<mlir::acc::CreateOp, mlir::acc::DeleteOp>( accObjectList, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_create, @@ -4378,11 +4541,9 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, } else if (const auto *copyoutClause = std::get_if<Fortran::parser::AccClause::Copyout>( &clause.u)) { - const Fortran::parser::AccObjectListWithModifier &listWithModifier = - copyoutClause->v; - const auto &accObjectList = - std::get<Fortran::parser::AccObjectList>(listWithModifier.t); auto crtDataStart = dataClauseOperands.size(); + const auto &accObjectList = + std::get<Fortran::parser::AccObjectList>(copyoutClause->v.t); genDeclareDataOperandOperations<mlir::acc::CreateOp, mlir::acc::CopyoutOp>( accObjectList, converter, semanticsContext, stmtCtx, @@ -4423,6 +4584,11 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, } } + // If no structured operands were generated (all objects were COMMON), + // do not create a declare region. + if (dataClauseOperands.empty()) + return; + mlir::func::FuncOp funcOp = builder.getFunction(); auto ops = funcOp.getOps<mlir::acc::DeclareEnterOp>(); mlir::Value declareToken; diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 85398be..1c163e6 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -1080,9 +1080,8 @@ bool ClauseProcessor::processHasDeviceAddr( [&](const omp::clause::HasDeviceAddr &clause, const parser::CharBlock &source) { mlir::Location location = converter.genLocation(source); - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT; + mlir::omp::ClauseMapFlags mapTypeBits = + mlir::omp::ClauseMapFlags::to | mlir::omp::ClauseMapFlags::implicit; omp::ObjectList baseObjects; llvm::transform(clause.v, std::back_inserter(baseObjects), [&](const omp::Object &object) { @@ -1217,8 +1216,7 @@ bool ClauseProcessor::processLink( void ClauseProcessor::processMapObjects( lower::StatementContext &stmtCtx, mlir::Location clauseLocation, - const omp::ObjectList &objects, - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits, + const omp::ObjectList &objects, mlir::omp::ClauseMapFlags mapTypeBits, std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices, llvm::SmallVectorImpl<mlir::Value> &mapVars, llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms, @@ -1310,10 +1308,7 @@ void ClauseProcessor::processMapObjects( mlir::omp::MapInfoOp mapOp = utils::openmp::createMapInfoOp( firOpBuilder, location, baseOp, /*varPtrPtr=*/mlir::Value{}, asFortran.str(), bounds, - /*members=*/{}, /*membersIndex=*/mlir::ArrayAttr{}, - static_cast< - std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>( - mapTypeBits), + /*members=*/{}, /*membersIndex=*/mlir::ArrayAttr{}, mapTypeBits, mlir::omp::VariableCaptureKind::ByRef, baseOp.getType(), /*partialMap=*/false, mapperId); @@ -1347,8 +1342,7 @@ bool ClauseProcessor::processMap( objects] = clause.t; if (attachMod) TODO(currentLocation, "ATTACH modifier is not implemented yet"); - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE; + mlir::omp::ClauseMapFlags mapTypeBits = mlir::omp::ClauseMapFlags::none; std::string mapperIdName = "__implicit_mapper"; // If the map type is specified, then process it else set the appropriate // default value @@ -1364,36 +1358,32 @@ bool ClauseProcessor::processMap( switch (type) { case Map::MapType::To: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; + mapTypeBits |= mlir::omp::ClauseMapFlags::to; break; case Map::MapType::From: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + mapTypeBits |= mlir::omp::ClauseMapFlags::from; break; case Map::MapType::Tofrom: - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + mapTypeBits |= + mlir::omp::ClauseMapFlags::to | mlir::omp::ClauseMapFlags::from; break; case Map::MapType::Storage: - // alloc and release is the default map_type for the Target Data - // Ops, i.e. if no bits for map_type is supplied then alloc/release - // (aka storage in 6.0+) is implicitly assumed based on the target - // directive. Default value for Target Data and Enter Data is alloc - // and for Exit Data it is release. + mapTypeBits |= mlir::omp::ClauseMapFlags::storage; break; } if (typeMods) { // TODO: Still requires "self" modifier, an OpenMP 6.0+ feature if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Always)) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS; + mapTypeBits |= mlir::omp::ClauseMapFlags::always; if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Present)) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT; + mapTypeBits |= mlir::omp::ClauseMapFlags::present; if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Close)) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE; + mapTypeBits |= mlir::omp::ClauseMapFlags::close; if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Delete)) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE; + mapTypeBits |= mlir::omp::ClauseMapFlags::del; if (llvm::is_contained(*typeMods, Map::MapTypeModifier::OmpxHold)) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD; + mapTypeBits |= mlir::omp::ClauseMapFlags::ompx_hold; } if (iterator) { @@ -1437,12 +1427,12 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx, TODO(clauseLocation, "Iterator modifier is not supported yet"); } - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = + mlir::omp::ClauseMapFlags mapTypeBits = std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To> - ? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO - : llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + ? mlir::omp::ClauseMapFlags::to + : mlir::omp::ClauseMapFlags::from; if (expectation && *expectation == omp::clause::To::Expectation::Present) - mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT; + mapTypeBits |= mlir::omp::ClauseMapFlags::present; processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits, parentMemberIndices, result.mapVars, mapSymbols); }; @@ -1568,8 +1558,8 @@ bool ClauseProcessor::processUseDeviceAddr( [&](const omp::clause::UseDeviceAddr &clause, const parser::CharBlock &source) { mlir::Location location = converter.genLocation(source); - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + mlir::omp::ClauseMapFlags mapTypeBits = + mlir::omp::ClauseMapFlags::return_param; processMapObjects(stmtCtx, location, clause.v, mapTypeBits, parentMemberIndices, result.useDeviceAddrVars, useDeviceSyms); @@ -1589,8 +1579,8 @@ bool ClauseProcessor::processUseDevicePtr( [&](const omp::clause::UseDevicePtr &clause, const parser::CharBlock &source) { mlir::Location location = converter.genLocation(source); - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + mlir::omp::ClauseMapFlags mapTypeBits = + mlir::omp::ClauseMapFlags::return_param; processMapObjects(stmtCtx, location, clause.v, mapTypeBits, parentMemberIndices, result.useDevicePtrVars, useDeviceSyms); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 9e352fa..6452e39 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -194,8 +194,7 @@ private: void processMapObjects( lower::StatementContext &stmtCtx, mlir::Location clauseLocation, - const omp::ObjectList &objects, - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits, + const omp::ObjectList &objects, mlir::omp::ClauseMapFlags mapTypeBits, std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices, llvm::SmallVectorImpl<mlir::Value> &mapVars, llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms, diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 2a4ebf1..d39f9dd 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -16,8 +16,6 @@ #include "flang/Semantics/openmp-modifiers.h" #include "flang/Semantics/symbol.h" -#include "llvm/Frontend/OpenMP/OMPConstants.h" - #include <list> #include <optional> #include <tuple> diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 9495ea6..7106728 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -45,7 +45,6 @@ #include "mlir/Support/StateStack.h" #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Frontend/OpenMP/OMPConstants.h" using namespace Fortran::lower::omp; using namespace Fortran::common::openmp; @@ -945,8 +944,7 @@ getDefaultmapIfPresent(const DefaultMapsTy &defaultMaps, mlir::Type varType) { return DefMap::ImplicitBehavior::Default; } -static std::pair<llvm::omp::OpenMPOffloadMappingFlags, - mlir::omp::VariableCaptureKind> +static std::pair<mlir::omp::ClauseMapFlags, mlir::omp::VariableCaptureKind> getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, lower::AbstractConverter &converter, const DefaultMapsTy &defaultMaps, mlir::Type varType, @@ -967,8 +965,7 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, return size <= ptrSize && align <= ptrAlign; }; - llvm::omp::OpenMPOffloadMappingFlags mapFlag = - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT; + mlir::omp::ClauseMapFlags mapFlag = mlir::omp::ClauseMapFlags::implicit; auto implicitBehaviour = getDefaultmapIfPresent(defaultMaps, varType); if (implicitBehaviour == DefMap::ImplicitBehavior::Default) { @@ -986,8 +983,8 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, mlir::omp::DeclareTargetCaptureClause::link && declareTargetOp.getDeclareTargetDeviceType() != mlir::omp::DeclareTargetDeviceType::nohost) { - mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; - mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + mapFlag |= mlir::omp::ClauseMapFlags::to; + mapFlag |= mlir::omp::ClauseMapFlags::from; } } else if (fir::isa_trivial(varType) || fir::isa_char(varType)) { // Scalars behave as if they were "firstprivate". @@ -996,18 +993,18 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, if (isLiteralType(varType)) { captureKind = mlir::omp::VariableCaptureKind::ByCopy; } else { - mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; + mapFlag |= mlir::omp::ClauseMapFlags::to; } } else if (!fir::isa_builtin_cptr_type(varType)) { - mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; - mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + mapFlag |= mlir::omp::ClauseMapFlags::to; + mapFlag |= mlir::omp::ClauseMapFlags::from; } return std::make_pair(mapFlag, captureKind); } switch (implicitBehaviour) { case DefMap::ImplicitBehavior::Alloc: - return std::make_pair(llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE, + return std::make_pair(mlir::omp::ClauseMapFlags::storage, mlir::omp::VariableCaptureKind::ByRef); break; case DefMap::ImplicitBehavior::Firstprivate: @@ -1016,26 +1013,22 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, "behaviour"); break; case DefMap::ImplicitBehavior::From: - return std::make_pair(mapFlag |= - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM, + return std::make_pair(mapFlag |= mlir::omp::ClauseMapFlags::from, mlir::omp::VariableCaptureKind::ByRef); break; case DefMap::ImplicitBehavior::Present: - return std::make_pair(mapFlag |= - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT, + return std::make_pair(mapFlag |= mlir::omp::ClauseMapFlags::present, mlir::omp::VariableCaptureKind::ByRef); break; case DefMap::ImplicitBehavior::To: - return std::make_pair(mapFlag |= - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO, + return std::make_pair(mapFlag |= mlir::omp::ClauseMapFlags::to, (fir::isa_trivial(varType) || fir::isa_char(varType)) ? mlir::omp::VariableCaptureKind::ByCopy : mlir::omp::VariableCaptureKind::ByRef); break; case DefMap::ImplicitBehavior::Tofrom: - return std::make_pair(mapFlag |= - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM | - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO, + return std::make_pair(mapFlag |= mlir::omp::ClauseMapFlags::from | + mlir::omp::ClauseMapFlags::to, mlir::omp::VariableCaptureKind::ByRef); break; case DefMap::ImplicitBehavior::Default: @@ -1044,9 +1037,8 @@ getImplicitMapTypeAndKind(fir::FirOpBuilder &firOpBuilder, break; } - return std::make_pair(mapFlag |= - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM | - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO, + return std::make_pair(mapFlag |= mlir::omp::ClauseMapFlags::from | + mlir::omp::ClauseMapFlags::to, mlir::omp::VariableCaptureKind::ByRef); } @@ -2067,37 +2059,38 @@ static void genCanonicalLoopNest( // Start lowering mlir::Value zero = firOpBuilder.createIntegerConstant(loc, loopVarType, 0); mlir::Value one = firOpBuilder.createIntegerConstant(loc, loopVarType, 1); - mlir::Value isDownwards = firOpBuilder.create<mlir::arith::CmpIOp>( - loc, mlir::arith::CmpIPredicate::slt, loopStepVar, zero); + mlir::Value isDownwards = mlir::arith::CmpIOp::create( + firOpBuilder, loc, mlir::arith::CmpIPredicate::slt, loopStepVar, zero); // Ensure we are counting upwards. If not, negate step and swap lb and ub. mlir::Value negStep = - firOpBuilder.create<mlir::arith::SubIOp>(loc, zero, loopStepVar); - mlir::Value incr = firOpBuilder.create<mlir::arith::SelectOp>( - loc, isDownwards, negStep, loopStepVar); - mlir::Value lb = firOpBuilder.create<mlir::arith::SelectOp>( - loc, isDownwards, loopUBVar, loopLBVar); - mlir::Value ub = firOpBuilder.create<mlir::arith::SelectOp>( - loc, isDownwards, loopLBVar, loopUBVar); + mlir::arith::SubIOp::create(firOpBuilder, loc, zero, loopStepVar); + mlir::Value incr = mlir::arith::SelectOp::create( + firOpBuilder, loc, isDownwards, negStep, loopStepVar); + mlir::Value lb = mlir::arith::SelectOp::create( + firOpBuilder, loc, isDownwards, loopUBVar, loopLBVar); + mlir::Value ub = mlir::arith::SelectOp::create( + firOpBuilder, loc, isDownwards, loopLBVar, loopUBVar); // Compute the trip count assuming lb <= ub. This guarantees that the result // is non-negative and we can use unsigned arithmetic. - mlir::Value span = firOpBuilder.create<mlir::arith::SubIOp>( - loc, ub, lb, ::mlir::arith::IntegerOverflowFlags::nuw); + mlir::Value span = mlir::arith::SubIOp::create( + firOpBuilder, loc, ub, lb, ::mlir::arith::IntegerOverflowFlags::nuw); mlir::Value tcMinusOne = - firOpBuilder.create<mlir::arith::DivUIOp>(loc, span, incr); - mlir::Value tcIfLooping = firOpBuilder.create<mlir::arith::AddIOp>( - loc, tcMinusOne, one, ::mlir::arith::IntegerOverflowFlags::nuw); + mlir::arith::DivUIOp::create(firOpBuilder, loc, span, incr); + mlir::Value tcIfLooping = + mlir::arith::AddIOp::create(firOpBuilder, loc, tcMinusOne, one, + ::mlir::arith::IntegerOverflowFlags::nuw); // Fall back to 0 if lb > ub - mlir::Value isZeroTC = firOpBuilder.create<mlir::arith::CmpIOp>( - loc, mlir::arith::CmpIPredicate::slt, ub, lb); - mlir::Value tripcount = firOpBuilder.create<mlir::arith::SelectOp>( - loc, isZeroTC, zero, tcIfLooping); + mlir::Value isZeroTC = mlir::arith::CmpIOp::create( + firOpBuilder, loc, mlir::arith::CmpIPredicate::slt, ub, lb); + mlir::Value tripcount = mlir::arith::SelectOp::create( + firOpBuilder, loc, isZeroTC, zero, tcIfLooping); tripcounts.push_back(tripcount); // Create the CLI handle. - auto newcli = firOpBuilder.create<mlir::omp::NewCliOp>(loc); + auto newcli = mlir::omp::NewCliOp::create(firOpBuilder, loc); mlir::Value cli = newcli.getResult(); clis.push_back(cli); @@ -2130,10 +2123,10 @@ static void genCanonicalLoopNest( "Expecting all block args to have been collected by now"); for (auto j : llvm::seq<size_t>(numLoops)) { mlir::Value natIterNum = fir::getBase(blockArgs[j]); - mlir::Value scaled = firOpBuilder.create<mlir::arith::MulIOp>( - loc, natIterNum, loopStepVars[j]); - mlir::Value userVal = firOpBuilder.create<mlir::arith::AddIOp>( - loc, loopLBVars[j], scaled); + mlir::Value scaled = mlir::arith::MulIOp::create( + firOpBuilder, loc, natIterNum, loopStepVars[j]); + mlir::Value userVal = mlir::arith::AddIOp::create( + firOpBuilder, loc, loopLBVars[j], scaled); mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint(); @@ -2206,9 +2199,9 @@ static void genTileOp(Fortran::lower::AbstractConverter &converter, gridGeneratees.reserve(numLoops); intratileGeneratees.reserve(numLoops); for ([[maybe_unused]] auto i : llvm::seq<int>(0, sizesClause.sizes.size())) { - auto gridCLI = firOpBuilder.create<mlir::omp::NewCliOp>(loc); + auto gridCLI = mlir::omp::NewCliOp::create(firOpBuilder, loc); gridGeneratees.push_back(gridCLI.getResult()); - auto intratileCLI = firOpBuilder.create<mlir::omp::NewCliOp>(loc); + auto intratileCLI = mlir::omp::NewCliOp::create(firOpBuilder, loc); intratileGeneratees.push_back(intratileCLI.getResult()); } @@ -2217,8 +2210,8 @@ static void genTileOp(Fortran::lower::AbstractConverter &converter, generatees.append(gridGeneratees); generatees.append(intratileGeneratees); - firOpBuilder.create<mlir::omp::TileOp>(loc, generatees, applyees, - sizesClause.sizes); + mlir::omp::TileOp::create(firOpBuilder, loc, generatees, applyees, + sizesClause.sizes); } static void genUnrollOp(Fortran::lower::AbstractConverter &converter, @@ -2612,18 +2605,14 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable, if (auto refType = mlir::dyn_cast<fir::ReferenceType>(baseOp.getType())) eleType = refType.getElementType(); - std::pair<llvm::omp::OpenMPOffloadMappingFlags, - mlir::omp::VariableCaptureKind> + std::pair<mlir::omp::ClauseMapFlags, mlir::omp::VariableCaptureKind> mapFlagAndKind = getImplicitMapTypeAndKind( firOpBuilder, converter, defaultMaps, eleType, loc, sym); mlir::Value mapOp = createMapInfoOp( firOpBuilder, converter.getCurrentLocation(), baseOp, /*varPtrPtr=*/mlir::Value{}, name.str(), bounds, /*members=*/{}, - /*membersIndex=*/mlir::ArrayAttr{}, - static_cast< - std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>( - std::get<0>(mapFlagAndKind)), + /*membersIndex=*/mlir::ArrayAttr{}, std::get<0>(mapFlagAndKind), std::get<1>(mapFlagAndKind), baseOp.getType(), /*partialMap=*/false, mapperId); diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index 37b926e..6487f59 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -273,7 +273,7 @@ mlir::Value createParentSymAndGenIntermediateMaps( semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx, omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices, OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran, - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits) { + mlir::omp::ClauseMapFlags mapTypeBits) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); /// Checks if an omp::Object is an array expression with a subscript, e.g. @@ -414,11 +414,10 @@ mlir::Value createParentSymAndGenIntermediateMaps( // be safer to just pass OMP_MAP_NONE as the map type, but we may still // need some of the other map types the mapped member utilises, so for // now it's good to keep an eye on this. - llvm::omp::OpenMPOffloadMappingFlags interimMapType = mapTypeBits; - interimMapType &= ~llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; - interimMapType &= ~llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; - interimMapType &= - ~llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + mlir::omp::ClauseMapFlags interimMapType = mapTypeBits; + interimMapType &= ~mlir::omp::ClauseMapFlags::to; + interimMapType &= ~mlir::omp::ClauseMapFlags::from; + interimMapType &= ~mlir::omp::ClauseMapFlags::return_param; // Create a map for the intermediate member and insert it and it's // indices into the parentMemberIndices list to track it. @@ -427,10 +426,7 @@ mlir::Value createParentSymAndGenIntermediateMaps( /*varPtrPtr=*/mlir::Value{}, asFortran, /*bounds=*/interimBounds, /*members=*/{}, - /*membersIndex=*/mlir::ArrayAttr{}, - static_cast< - std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>( - interimMapType), + /*membersIndex=*/mlir::ArrayAttr{}, interimMapType, mlir::omp::VariableCaptureKind::ByRef, curValue.getType()); parentMemberIndices.memberPlacementIndices.push_back(interimIndices); @@ -563,7 +559,8 @@ void insertChildMapInfoIntoParent( // it allows this to work with enter and exit without causing MLIR // verification issues. The more appropriate thing may be to take // the "main" map type clause from the directive being used. - uint64_t mapType = indices.second.memberMap[0].getMapType(); + mlir::omp::ClauseMapFlags mapType = + indices.second.memberMap[0].getMapType(); llvm::SmallVector<mlir::Value> members; members.reserve(indices.second.memberMap.size()); diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h index 69499f9..ef1f37a 100644 --- a/flang/lib/Lower/OpenMP/Utils.h +++ b/flang/lib/Lower/OpenMP/Utils.h @@ -134,7 +134,7 @@ mlir::Value createParentSymAndGenIntermediateMaps( semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx, omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices, OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran, - llvm::omp::OpenMPOffloadMappingFlags mapTypeBits); + mlir::omp::ClauseMapFlags mapTypeBits); omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember, semantics::SemanticsContext &semaCtx); |