@@ -1700,6 +1700,7 @@ static void genTargetClauses(
1700
1700
lower::SymMap &symTable, lower::StatementContext &stmtCtx,
1701
1701
lower::pft::Evaluation &eval, const List<Clause> &clauses,
1702
1702
mlir::Location loc, mlir::omp::TargetOperands &clauseOps,
1703
+ DefaultMapsTy &defaultMaps,
1703
1704
llvm::SmallVectorImpl<const semantics::Symbol *> &hasDeviceAddrSyms,
1704
1705
llvm::SmallVectorImpl<const semantics::Symbol *> &isDevicePtrSyms,
1705
1706
llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms) {
@@ -1718,10 +1719,11 @@ static void genTargetClauses(
1718
1719
cp.processMap (loc, stmtCtx, clauseOps, &mapSyms);
1719
1720
cp.processNowait (clauseOps);
1720
1721
cp.processThreadLimit (stmtCtx, clauseOps);
1722
+ cp.processDefaultMap (defaultMaps, stmtCtx);
1721
1723
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);
1725
1727
1726
1728
// `target private(..)` is only supported in delayed privatization mode.
1727
1729
if (!enableDelayedPrivatizationStaging)
@@ -2246,10 +2248,12 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2246
2248
hostEvalInfo.emplace_back ();
2247
2249
2248
2250
mlir::omp::TargetOperands clauseOps;
2251
+ DefaultMapsTy defaultMaps;
2249
2252
llvm::SmallVector<const semantics::Symbol *> mapSyms, isDevicePtrSyms,
2250
2253
hasDeviceAddrSyms;
2251
2254
genTargetClauses (converter, semaCtx, symTable, stmtCtx, eval, item->clauses ,
2252
- loc, clauseOps, hasDeviceAddrSyms, isDevicePtrSyms, mapSyms);
2255
+ loc, clauseOps, defaultMaps, hasDeviceAddrSyms,
2256
+ isDevicePtrSyms, mapSyms);
2253
2257
2254
2258
DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
2255
2259
/* shouldCollectPreDeterminedSymbols=*/
@@ -2272,6 +2276,129 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2272
2276
return size <= ptrSize && align <= ptrAlign;
2273
2277
};
2274
2278
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
+
2275
2402
// 5.8.1 Implicit Data-Mapping Attribute Rules
2276
2403
// The following code follows the implicit data-mapping rules to map all the
2277
2404
// symbols used inside the region that do not have explicit data-environment
@@ -2327,62 +2454,32 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
2327
2454
fir::factory::AddrAndBoundsInfo info =
2328
2455
Fortran::lower::getDataOperandBaseAddr (
2329
2456
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;
2341
2457
2342
2458
mlir::Value baseOp = info.rawInput ;
2343
2459
mlir::Type eleType = baseOp.getType ();
2344
2460
if (auto refType = mlir::dyn_cast<fir::ReferenceType>(baseOp.getType ()))
2345
2461
eleType = refType.getElementType ();
2346
2462
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 ());
2378
2474
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=*/ {},
2381
2477
/* membersIndex=*/ mlir::ArrayAttr{},
2382
2478
static_cast <
2383
2479
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);
2386
2483
2387
2484
clauseOps.mapVars .push_back (mapOp);
2388
2485
mapSyms.push_back (&sym);
@@ -3539,6 +3636,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3539
3636
!std::holds_alternative<clause::Copyin>(clause.u ) &&
3540
3637
!std::holds_alternative<clause::Copyprivate>(clause.u ) &&
3541
3638
!std::holds_alternative<clause::Default>(clause.u ) &&
3639
+ !std::holds_alternative<clause::Defaultmap>(clause.u ) &&
3542
3640
!std::holds_alternative<clause::Depend>(clause.u ) &&
3543
3641
!std::holds_alternative<clause::Filter>(clause.u ) &&
3544
3642
!std::holds_alternative<clause::Final>(clause.u ) &&
0 commit comments