@@ -1700,6 +1700,7 @@ static void genTargetClauses(
17001700 lower::SymMap &symTable, lower::StatementContext &stmtCtx,
17011701 lower::pft::Evaluation &eval, const List<Clause> &clauses,
17021702 mlir::Location loc, mlir::omp::TargetOperands &clauseOps,
1703+ DefaultMapsTy &defaultMaps,
17031704 llvm::SmallVectorImpl<const semantics::Symbol *> &hasDeviceAddrSyms,
17041705 llvm::SmallVectorImpl<const semantics::Symbol *> &isDevicePtrSyms,
17051706 llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms) {
@@ -1718,10 +1719,11 @@ static void genTargetClauses(
17181719 cp.processMap (loc, stmtCtx, clauseOps, &mapSyms);
17191720 cp.processNowait (clauseOps);
17201721 cp.processThreadLimit (stmtCtx, clauseOps);
1722+ cp.processDefaultMap (defaultMaps, stmtCtx);
17211723
1722- cp.processTODO <clause::Allocate, clause::Defaultmap , clause::Firstprivate ,
1723- clause::InReduction, clause:: UsesAllocators>(
1724- loc, llvm::omp::Directive::OMPD_target);
1724+ cp.processTODO <clause::Allocate, clause::Firstprivate , clause::InReduction ,
1725+ clause::UsesAllocators>(loc,
1726+ llvm::omp::Directive::OMPD_target);
17251727
17261728 // `target private(..)` is only supported in delayed privatization mode.
17271729 if (!enableDelayedPrivatizationStaging)
@@ -2246,10 +2248,12 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
22462248 hostEvalInfo.emplace_back ();
22472249
22482250 mlir::omp::TargetOperands clauseOps;
2251+ DefaultMapsTy defaultMaps;
22492252 llvm::SmallVector<const semantics::Symbol *> mapSyms, isDevicePtrSyms,
22502253 hasDeviceAddrSyms;
22512254 genTargetClauses (converter, semaCtx, symTable, stmtCtx, eval, item->clauses ,
2252- loc, clauseOps, hasDeviceAddrSyms, isDevicePtrSyms, mapSyms);
2255+ loc, clauseOps, defaultMaps, hasDeviceAddrSyms,
2256+ isDevicePtrSyms, mapSyms);
22532257
22542258 DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
22552259 /* shouldCollectPreDeterminedSymbols=*/
@@ -2272,6 +2276,129 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
22722276 return size <= ptrSize && align <= ptrAlign;
22732277 };
22742278
2279+ auto getDefaultmapIfPresent = [&](mlir::Type varType) {
2280+ using defMap = clause::Defaultmap;
2281+ auto exists = [&](defMap::VariableCategory varCat) {
2282+ return defaultMaps.find (varCat) != defaultMaps.end ();
2283+ };
2284+
2285+ if (defaultMaps.empty ())
2286+ return defMap::ImplicitBehavior::Default;
2287+
2288+ if (exists (defMap::VariableCategory::All))
2289+ return defaultMaps[defMap::VariableCategory::All];
2290+
2291+ // NOTE: Unsure if complex and/or vector falls into a scalar type
2292+ // or aggregate, but the current default implicit behaviour is to
2293+ // treat them as such (c_ptr has its own behaviour, so perhaps
2294+ // being lumped in as a scalar isn't the right thing).
2295+ if ((fir::isa_trivial (varType) || fir::isa_char (varType) ||
2296+ fir::isa_builtin_cptr_type (varType)) &&
2297+ exists (defMap::VariableCategory::Scalar))
2298+ return defaultMaps[defMap::VariableCategory::Scalar];
2299+
2300+ if (fir::isPointerType (varType) &&
2301+ exists (defMap::VariableCategory::Pointer))
2302+ return defaultMaps[defMap::VariableCategory::Pointer];
2303+
2304+ if (fir::isAllocatableType (varType) &&
2305+ exists (defMap::VariableCategory::Allocatable))
2306+ return defaultMaps[defMap::VariableCategory::Allocatable];
2307+
2308+ if (fir::isa_aggregate (varType) &&
2309+ exists (defMap::VariableCategory::Aggregate)) {
2310+ return defaultMaps[defMap::VariableCategory::Aggregate];
2311+ }
2312+
2313+ return defMap::ImplicitBehavior::Default;
2314+ };
2315+
2316+ auto getImplicitMapTypeAndKind = [&](mlir::Type varType,
2317+ const semantics::Symbol &sym) {
2318+ using defMap = clause::Defaultmap;
2319+ llvm::omp::OpenMPOffloadMappingFlags mapFlag =
2320+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
2321+
2322+ auto implicitBehaviour = getDefaultmapIfPresent (varType);
2323+ if (implicitBehaviour == defMap::ImplicitBehavior::Default) {
2324+ mlir::omp::VariableCaptureKind captureKind =
2325+ mlir::omp::VariableCaptureKind::ByRef;
2326+
2327+ // If a variable is specified in declare target link and if device
2328+ // type is not specified as `nohost`, it needs to be mapped tofrom
2329+ mlir::ModuleOp mod = firOpBuilder.getModule ();
2330+ mlir::Operation *op = mod.lookupSymbol (converter.mangleName (sym));
2331+ auto declareTargetOp =
2332+ llvm::dyn_cast_if_present<mlir::omp::DeclareTargetInterface>(op);
2333+ if (declareTargetOp && declareTargetOp.isDeclareTarget ()) {
2334+ if (declareTargetOp.getDeclareTargetCaptureClause () ==
2335+ mlir::omp::DeclareTargetCaptureClause::link &&
2336+ declareTargetOp.getDeclareTargetDeviceType () !=
2337+ mlir::omp::DeclareTargetDeviceType::nohost) {
2338+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2339+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
2340+ }
2341+ } else if (fir::isa_trivial (varType) || fir::isa_char (varType)) {
2342+ // Scalars behave as if they were "firstprivate".
2343+ // TODO: Handle objects that are shared/lastprivate or were listed
2344+ // in an in_reduction clause.
2345+ if (isLiteralType (varType)) {
2346+ captureKind = mlir::omp::VariableCaptureKind::ByCopy;
2347+ } else {
2348+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2349+ }
2350+ } else if (!fir::isa_builtin_cptr_type (varType)) {
2351+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2352+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
2353+ }
2354+ return std::make_pair (mapFlag, captureKind);
2355+ }
2356+
2357+ switch (implicitBehaviour) {
2358+ case defMap::ImplicitBehavior::Alloc:
2359+ return std::make_pair (llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE,
2360+ mlir::omp::VariableCaptureKind::ByRef);
2361+ break ;
2362+ case defMap::ImplicitBehavior::Firstprivate:
2363+ case defMap::ImplicitBehavior::None:
2364+ TODO (loc, " Firstprivate and None are currently unsupported defaultmap "
2365+ " behaviour" );
2366+ break ;
2367+ case defMap::ImplicitBehavior::From:
2368+ return std::make_pair (mapFlag |=
2369+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM,
2370+ mlir::omp::VariableCaptureKind::ByRef);
2371+ break ;
2372+ case defMap::ImplicitBehavior::Present:
2373+ return std::make_pair (
2374+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT,
2375+ mlir::omp::VariableCaptureKind::ByRef);
2376+ break ;
2377+ case defMap::ImplicitBehavior::To:
2378+ return std::make_pair (
2379+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO,
2380+ (fir::isa_trivial (varType) || fir::isa_char (varType))
2381+ ? mlir::omp::VariableCaptureKind::ByCopy
2382+ : mlir::omp::VariableCaptureKind::ByRef);
2383+ break ;
2384+ case defMap::ImplicitBehavior::Tofrom:
2385+ return std::make_pair (mapFlag |=
2386+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM |
2387+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO,
2388+ mlir::omp::VariableCaptureKind::ByRef);
2389+ break ;
2390+ case defMap::ImplicitBehavior::Default:
2391+ llvm_unreachable (
2392+ " Implicit None Behaviour Should Have Been Handled Earlier" );
2393+ break ;
2394+ }
2395+
2396+ return std::make_pair (mapFlag |=
2397+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM |
2398+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO,
2399+ mlir::omp::VariableCaptureKind::ByRef);
2400+ };
2401+
22752402 // 5.8.1 Implicit Data-Mapping Attribute Rules
22762403 // The following code follows the implicit data-mapping rules to map all the
22772404 // symbols used inside the region that do not have explicit data-environment
@@ -2327,62 +2454,32 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
23272454 fir::factory::AddrAndBoundsInfo info =
23282455 Fortran::lower::getDataOperandBaseAddr (
23292456 converter, firOpBuilder, sym, converter.getCurrentLocation ());
2330- llvm::SmallVector<mlir::Value> bounds =
2331- fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
2332- mlir::omp::MapBoundsType>(
2333- firOpBuilder, info, dataExv,
2334- semantics::IsAssumedSizeArray (sym.GetUltimate ()),
2335- converter.getCurrentLocation ());
2336-
2337- llvm::omp::OpenMPOffloadMappingFlags mapFlag =
2338- llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
2339- mlir::omp::VariableCaptureKind captureKind =
2340- mlir::omp::VariableCaptureKind::ByRef;
23412457
23422458 mlir::Value baseOp = info.rawInput ;
23432459 mlir::Type eleType = baseOp.getType ();
23442460 if (auto refType = mlir::dyn_cast<fir::ReferenceType>(baseOp.getType ()))
23452461 eleType = refType.getElementType ();
23462462
2347- // If a variable is specified in declare target link and if device
2348- // type is not specified as `nohost`, it needs to be mapped tofrom
2349- mlir::ModuleOp mod = firOpBuilder.getModule ();
2350- mlir::Operation *op = mod.lookupSymbol (converter.mangleName (sym));
2351- auto declareTargetOp =
2352- llvm::dyn_cast_if_present<mlir::omp::DeclareTargetInterface>(op);
2353- if (declareTargetOp && declareTargetOp.isDeclareTarget ()) {
2354- if (declareTargetOp.getDeclareTargetCaptureClause () ==
2355- mlir::omp::DeclareTargetCaptureClause::link &&
2356- declareTargetOp.getDeclareTargetDeviceType () !=
2357- mlir::omp::DeclareTargetDeviceType::nohost) {
2358- mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2359- mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
2360- }
2361- } else if (fir::isa_trivial (eleType) || fir::isa_char (eleType)) {
2362- // Scalars behave as if they were "firstprivate".
2363- // TODO: Handle objects that are shared/lastprivate or were listed
2364- // in an in_reduction clause.
2365- if (isLiteralType (eleType)) {
2366- captureKind = mlir::omp::VariableCaptureKind::ByCopy;
2367- } else {
2368- mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2369- }
2370- } else if (!fir::isa_builtin_cptr_type (eleType)) {
2371- mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
2372- mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
2373- }
2374- auto location =
2375- mlir::NameLoc::get (mlir::StringAttr::get (firOpBuilder.getContext (),
2376- sym.name ().ToString ()),
2377- baseOp.getLoc ());
2463+ auto mapFlagAndKind = getImplicitMapTypeAndKind (eleType, sym);
2464+
2465+ llvm::SmallVector<mlir::Value> bounds =
2466+ fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
2467+ mlir::omp::MapBoundsType>(
2468+ firOpBuilder, info, dataExv,
2469+ semantics::IsAssumedSizeArray (sym.GetUltimate ()),
2470+ converter.getCurrentLocation ());
2471+ mlir::NameLoc::get (mlir::StringAttr::get (firOpBuilder.getContext (),
2472+ sym.name ().ToString ()),
2473+ baseOp.getLoc ());
23782474 mlir::Value mapOp = createMapInfoOp (
2379- firOpBuilder, location , baseOp, /* varPtrPtr= */ mlir::Value{} ,
2380- name.str (), bounds, /* members=*/ {},
2475+ firOpBuilder, converter. getCurrentLocation () , baseOp,
2476+ /* varPtrPtr= */ mlir::Value{}, name.str (), bounds, /* members=*/ {},
23812477 /* membersIndex=*/ mlir::ArrayAttr{},
23822478 static_cast <
23832479 std::underlying_type_t <llvm::omp::OpenMPOffloadMappingFlags>>(
2384- mapFlag),
2385- captureKind, baseOp.getType (), /* partialMap=*/ false , mapperId);
2480+ std::get<0 >(mapFlagAndKind)),
2481+ std::get<1 >(mapFlagAndKind), baseOp.getType (),
2482+ /* partialMap=*/ false , mapperId);
23862483
23872484 clauseOps.mapVars .push_back (mapOp);
23882485 mapSyms.push_back (&sym);
@@ -3539,6 +3636,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35393636 !std::holds_alternative<clause::Copyin>(clause.u ) &&
35403637 !std::holds_alternative<clause::Copyprivate>(clause.u ) &&
35413638 !std::holds_alternative<clause::Default>(clause.u ) &&
3639+ !std::holds_alternative<clause::Defaultmap>(clause.u ) &&
35423640 !std::holds_alternative<clause::Depend>(clause.u ) &&
35433641 !std::holds_alternative<clause::Filter>(clause.u ) &&
35443642 !std::holds_alternative<clause::Final>(clause.u ) &&
0 commit comments