21
21
#include " flang/Optimizer/Builder/FIRBuilder.h"
22
22
#include " flang/Optimizer/Builder/Todo.h"
23
23
#include " flang/Optimizer/HLFIR/HLFIROps.h"
24
+ #include " flang/Parser/dump-parse-tree.h"
24
25
#include " flang/Parser/parse-tree.h"
25
26
#include " flang/Semantics/openmp-directive-sets.h"
26
27
#include " flang/Semantics/tools.h"
@@ -549,15 +550,23 @@ class ClauseProcessor {
549
550
llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
550
551
&useDeviceSymbols) const ;
551
552
553
+ // Call this method for these clauses that should be supported but are not
554
+ // implemented yet. It triggers a compilation error if any of the given
555
+ // clauses is found.
556
+ template <typename ... Ts>
557
+ void processTODO (mlir::Location currentLocation,
558
+ llvm::omp::Directive directive) const ;
559
+
552
560
private:
553
561
using ClauseIterator = std::list<ClauseTy>::const_iterator;
554
562
555
563
// / Utility to find a clause within a range in the clause list.
556
564
template <typename T>
557
565
static ClauseIterator findClause (ClauseIterator begin, ClauseIterator end) {
558
- for (ClauseIterator it = begin; it != end; ++it)
566
+ for (ClauseIterator it = begin; it != end; ++it) {
559
567
if (std::get_if<T>(&it->u ))
560
568
return it;
569
+ }
561
570
562
571
return end;
563
572
}
@@ -1773,6 +1782,24 @@ bool ClauseProcessor::processUseDevicePtr(
1773
1782
});
1774
1783
}
1775
1784
1785
+ template <typename ... Ts>
1786
+ void ClauseProcessor::processTODO (mlir::Location currentLocation,
1787
+ llvm::omp::Directive directive) const {
1788
+ auto checkUnhandledClause = [&](const auto *x) {
1789
+ if (!x)
1790
+ return ;
1791
+ TODO (currentLocation,
1792
+ " Unhandled clause " +
1793
+ llvm::StringRef (Fortran::parser::ParseTreeDumper::GetNodeName (*x))
1794
+ .upper () +
1795
+ " in " + llvm::omp::getOpenMPDirectiveName (directive).upper () +
1796
+ " construct" );
1797
+ };
1798
+
1799
+ for (ClauseIterator it = clauses.v .begin (); it != clauses.v .end (); ++it)
1800
+ (checkUnhandledClause (std::get_if<Ts>(&it->u )), ...);
1801
+ }
1802
+
1776
1803
// ===----------------------------------------------------------------------===//
1777
1804
// Code generation helper functions
1778
1805
// ===----------------------------------------------------------------------===//
@@ -2213,8 +2240,11 @@ genSingleOp(Fortran::lower::AbstractConverter &converter,
2213
2240
llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands;
2214
2241
mlir::UnitAttr nowaitAttr;
2215
2242
2216
- ClauseProcessor (converter, beginClauseList)
2217
- .processAllocate (allocatorOperands, allocateOperands);
2243
+ ClauseProcessor cp (converter, beginClauseList);
2244
+ cp.processAllocate (allocatorOperands, allocateOperands);
2245
+ cp.processTODO <Fortran::parser::OmpClause::Copyprivate>(
2246
+ currentLocation, llvm::omp::Directive::OMPD_single);
2247
+
2218
2248
ClauseProcessor (converter, endClauseList).processNowait (nowaitAttr);
2219
2249
2220
2250
return genOpWithBody<mlir::omp::SingleOp>(
@@ -2244,6 +2274,10 @@ genTaskOp(Fortran::lower::AbstractConverter &converter,
2244
2274
cp.processMergeable (mergeableAttr);
2245
2275
cp.processPriority (stmtCtx, priorityClauseOperand);
2246
2276
cp.processDepend (dependTypeOperands, dependOperands);
2277
+ cp.processTODO <Fortran::parser::OmpClause::InReduction,
2278
+ Fortran::parser::OmpClause::Detach,
2279
+ Fortran::parser::OmpClause::Affinity>(
2280
+ currentLocation, llvm::omp::Directive::OMPD_task);
2247
2281
2248
2282
return genOpWithBody<mlir::omp::TaskOp>(
2249
2283
converter, eval, currentLocation, /* outerCombined=*/ false , &clauseList,
@@ -2263,9 +2297,10 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter,
2263
2297
mlir::Location currentLocation,
2264
2298
const Fortran::parser::OmpClauseList &clauseList) {
2265
2299
llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands;
2266
- // TODO: Add task_reduction support
2267
- ClauseProcessor (converter, clauseList)
2268
- .processAllocate (allocatorOperands, allocateOperands);
2300
+ ClauseProcessor cp (converter, clauseList);
2301
+ cp.processAllocate (allocatorOperands, allocateOperands);
2302
+ cp.processTODO <Fortran::parser::OmpClause::TaskReduction>(
2303
+ currentLocation, llvm::omp::Directive::OMPD_taskgroup);
2269
2304
return genOpWithBody<mlir::omp::TaskGroupOp>(
2270
2305
converter, eval, currentLocation, /* outerCombined=*/ false , &clauseList,
2271
2306
/* task_reduction_vars=*/ mlir::ValueRange (),
@@ -2323,12 +2358,15 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter,
2323
2358
llvm::SmallVector<mlir::IntegerAttr> mapTypes;
2324
2359
2325
2360
Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName;
2361
+ llvm::omp::Directive directive;
2326
2362
if constexpr (std::is_same_v<OpTy, mlir::omp::EnterDataOp>) {
2327
2363
directiveName =
2328
2364
Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetEnterData;
2365
+ directive = llvm::omp::Directive::OMPD_target_enter_data;
2329
2366
} else if constexpr (std::is_same_v<OpTy, mlir::omp::ExitDataOp>) {
2330
2367
directiveName =
2331
2368
Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetExitData;
2369
+ directive = llvm::omp::Directive::OMPD_target_exit_data;
2332
2370
} else {
2333
2371
return nullptr ;
2334
2372
}
@@ -2338,6 +2376,8 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter,
2338
2376
cp.processDevice (stmtCtx, deviceOperand);
2339
2377
cp.processNowait (nowaitAttr);
2340
2378
cp.processMap (mapOperands, mapTypes);
2379
+ cp.processTODO <Fortran::parser::OmpClause::Depend>(currentLocation,
2380
+ directive);
2341
2381
2342
2382
llvm::SmallVector<mlir::Attribute> mapTypesAttr (mapTypes.begin (),
2343
2383
mapTypes.end ());
@@ -2370,6 +2410,17 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
2370
2410
cp.processThreadLimit (stmtCtx, threadLimitOperand);
2371
2411
cp.processNowait (nowaitAttr);
2372
2412
cp.processMap (mapOperands, mapTypes);
2413
+ cp.processTODO <Fortran::parser::OmpClause::Private,
2414
+ Fortran::parser::OmpClause::Depend,
2415
+ Fortran::parser::OmpClause::Firstprivate,
2416
+ Fortran::parser::OmpClause::IsDevicePtr,
2417
+ Fortran::parser::OmpClause::HasDeviceAddr,
2418
+ Fortran::parser::OmpClause::Reduction,
2419
+ Fortran::parser::OmpClause::InReduction,
2420
+ Fortran::parser::OmpClause::Allocate,
2421
+ Fortran::parser::OmpClause::UsesAllocators,
2422
+ Fortran::parser::OmpClause::Defaultmap>(
2423
+ currentLocation, llvm::omp::Directive::OMPD_target);
2373
2424
2374
2425
llvm::SmallVector<mlir::Attribute> mapTypesAttr (mapTypes.begin (),
2375
2426
mapTypes.end ());
@@ -2402,8 +2453,8 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter,
2402
2453
cp.processDefault ();
2403
2454
cp.processNumTeams (stmtCtx, numTeamsClauseOperand);
2404
2455
cp.processThreadLimit (stmtCtx, threadLimitClauseOperand);
2405
- if ( cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols))
2406
- TODO ( currentLocation, " Reduction of TEAMS directive " );
2456
+ cp.processTODO <Fortran::parser::OmpClause::Reduction>(
2457
+ currentLocation, llvm::omp::Directive::OMPD_teams );
2407
2458
2408
2459
return genOpWithBody<mlir::omp::TeamsOp>(
2409
2460
converter, eval, currentLocation, outerCombined, &clauseList,
@@ -2420,10 +2471,11 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter,
2420
2471
// genOMP() Code generation helper functions
2421
2472
// ===----------------------------------------------------------------------===//
2422
2473
2423
- static void genOMP (Fortran::lower::AbstractConverter &converter,
2424
- Fortran::lower::pft::Evaluation &eval,
2425
- const Fortran::parser::OpenMPSimpleStandaloneConstruct
2426
- &simpleStandaloneConstruct) {
2474
+ static void
2475
+ genOmpSimpleStandalone (Fortran::lower::AbstractConverter &converter,
2476
+ Fortran::lower::pft::Evaluation &eval,
2477
+ const Fortran::parser::OpenMPSimpleStandaloneConstruct
2478
+ &simpleStandaloneConstruct) {
2427
2479
const auto &directive =
2428
2480
std::get<Fortran::parser::OmpSimpleStandaloneDirective>(
2429
2481
simpleStandaloneConstruct.t );
@@ -2439,6 +2491,10 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2439
2491
firOpBuilder.create <mlir::omp::BarrierOp>(currentLocation);
2440
2492
break ;
2441
2493
case llvm::omp::Directive::OMPD_taskwait:
2494
+ ClauseProcessor (converter, opClauseList)
2495
+ .processTODO <Fortran::parser::OmpClause::Depend,
2496
+ Fortran::parser::OmpClause::Nowait>(
2497
+ currentLocation, llvm::omp::Directive::OMPD_taskwait);
2442
2498
firOpBuilder.create <mlir::omp::TaskwaitOp>(currentLocation);
2443
2499
break ;
2444
2500
case llvm::omp::Directive::OMPD_taskyield:
@@ -2462,6 +2518,24 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2462
2518
}
2463
2519
}
2464
2520
2521
+ static void
2522
+ genOmpFlush (Fortran::lower::AbstractConverter &converter,
2523
+ Fortran::lower::pft::Evaluation &eval,
2524
+ const Fortran::parser::OpenMPFlushConstruct &flushConstruct) {
2525
+ llvm::SmallVector<mlir::Value, 4 > operandRange;
2526
+ if (const auto &ompObjectList =
2527
+ std::get<std::optional<Fortran::parser::OmpObjectList>>(
2528
+ flushConstruct.t ))
2529
+ genObjectList (*ompObjectList, converter, operandRange);
2530
+ const auto &memOrderClause =
2531
+ std::get<std::optional<std::list<Fortran::parser::OmpMemoryOrderClause>>>(
2532
+ flushConstruct.t );
2533
+ if (memOrderClause && memOrderClause->size () > 0 )
2534
+ TODO (converter.getCurrentLocation (), " Handle OmpMemoryOrderClause" );
2535
+ converter.getFirOpBuilder ().create <mlir::omp::FlushOp>(
2536
+ converter.getCurrentLocation (), operandRange);
2537
+ }
2538
+
2465
2539
static void
2466
2540
genOMP (Fortran::lower::AbstractConverter &converter,
2467
2541
Fortran::lower::pft::Evaluation &eval,
@@ -2470,22 +2544,10 @@ genOMP(Fortran::lower::AbstractConverter &converter,
2470
2544
Fortran::common::visitors{
2471
2545
[&](const Fortran::parser::OpenMPSimpleStandaloneConstruct
2472
2546
&simpleStandaloneConstruct) {
2473
- genOMP (converter, eval, simpleStandaloneConstruct);
2547
+ genOmpSimpleStandalone (converter, eval, simpleStandaloneConstruct);
2474
2548
},
2475
2549
[&](const Fortran::parser::OpenMPFlushConstruct &flushConstruct) {
2476
- llvm::SmallVector<mlir::Value, 4 > operandRange;
2477
- if (const auto &ompObjectList =
2478
- std::get<std::optional<Fortran::parser::OmpObjectList>>(
2479
- flushConstruct.t ))
2480
- genObjectList (*ompObjectList, converter, operandRange);
2481
- const auto &memOrderClause = std::get<std::optional<
2482
- std::list<Fortran::parser::OmpMemoryOrderClause>>>(
2483
- flushConstruct.t );
2484
- if (memOrderClause && memOrderClause->size () > 0 )
2485
- TODO (converter.getCurrentLocation (),
2486
- " Handle OmpMemoryOrderClause" );
2487
- converter.getFirOpBuilder ().create <mlir::omp::FlushOp>(
2488
- converter.getCurrentLocation (), operandRange);
2550
+ genOmpFlush (converter, eval, flushConstruct);
2489
2551
},
2490
2552
[&](const Fortran::parser::OpenMPCancelConstruct &cancelConstruct) {
2491
2553
TODO (converter.getCurrentLocation (), " OpenMPCancelConstruct" );
@@ -2503,14 +2565,13 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2503
2565
const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
2504
2566
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2505
2567
llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, linearVars,
2506
- linearStepVars, reductionVars, alignedVars, nontemporalVars ;
2507
- mlir::Value scheduleChunkClauseOperand, ifClauseOperand ;
2568
+ linearStepVars, reductionVars;
2569
+ mlir::Value scheduleChunkClauseOperand;
2508
2570
mlir::IntegerAttr orderedClauseOperand;
2509
2571
mlir::omp::ClauseOrderKindAttr orderClauseOperand;
2510
2572
mlir::omp::ClauseScheduleKindAttr scheduleValClauseOperand;
2511
2573
mlir::omp::ScheduleModifierAttr scheduleModClauseOperand;
2512
2574
mlir::UnitAttr nowaitClauseOperand, scheduleSimdClauseOperand;
2513
- mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
2514
2575
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
2515
2576
Fortran::lower::StatementContext stmtCtx;
2516
2577
std::size_t loopVarTypeSize;
@@ -2570,12 +2631,10 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2570
2631
cp.processCollapse (currentLocation, eval, lowerBound, upperBound, step, iv,
2571
2632
loopVarTypeSize);
2572
2633
cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
2573
- cp.processIf (stmtCtx,
2574
- Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd,
2575
- ifClauseOperand);
2576
2634
cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols);
2577
- cp.processSimdlen (simdlenClauseOperand);
2578
- cp.processSafelen (safelenClauseOperand);
2635
+ cp.processTODO <Fortran::parser::OmpClause::Linear,
2636
+ Fortran::parser::OmpClause::Order>(currentLocation,
2637
+ ompDirective);
2579
2638
2580
2639
// The types of lower bound, upper bound, and step are converted into the
2581
2640
// type of the loop variable if necessary.
@@ -2590,8 +2649,20 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2590
2649
}
2591
2650
2592
2651
// 2.9.3.1 SIMD construct
2593
- // TODO: Support all the clauses
2594
2652
if (llvm::omp::allSimdSet.test (ompDirective)) {
2653
+ llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars;
2654
+ mlir::Value ifClauseOperand;
2655
+ mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
2656
+ cp.processIf (stmtCtx,
2657
+ Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd,
2658
+ ifClauseOperand);
2659
+ cp.processSimdlen (simdlenClauseOperand);
2660
+ cp.processSafelen (safelenClauseOperand);
2661
+ cp.processTODO <Fortran::parser::OmpClause::Aligned,
2662
+ Fortran::parser::OmpClause::Allocate,
2663
+ Fortran::parser::OmpClause::Nontemporal>(currentLocation,
2664
+ ompDirective);
2665
+
2595
2666
mlir::TypeRange resultType;
2596
2667
auto simdLoopOp = firOpBuilder.create <mlir::omp::SimdLoopOp>(
2597
2668
currentLocation, resultType, lowerBound, upperBound, step, alignedVars,
@@ -2604,9 +2675,6 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
2604
2675
return ;
2605
2676
}
2606
2677
2607
- // FIXME: Add support for following clauses:
2608
- // 1. linear
2609
- // 2. order
2610
2678
auto wsLoopOp = firOpBuilder.create <mlir::omp::WsLoopOp>(
2611
2679
currentLocation, lowerBound, upperBound, step, linearVars, linearStepVars,
2612
2680
reductionVars,
@@ -3340,6 +3408,9 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
3340
3408
cp.processTo (symbolAndClause);
3341
3409
cp.processLink (symbolAndClause);
3342
3410
cp.processDeviceType (deviceType);
3411
+ cp.processTODO <Fortran::parser::OmpClause::Indirect>(
3412
+ converter.getCurrentLocation (),
3413
+ llvm::omp::Directive::OMPD_declare_target);
3343
3414
}
3344
3415
3345
3416
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
0 commit comments