1 //===-- OpenMP.cpp -- Open MP directive lowering --------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "flang/Lower/OpenMP.h" 14 #include "flang/Lower/Bridge.h" 15 #include "flang/Lower/FIRBuilder.h" 16 #include "flang/Lower/PFTBuilder.h" 17 #include "flang/Parser/parse-tree.h" 18 #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 19 #include "llvm/Frontend/OpenMP/OMPConstants.h" 20 21 #define TODO() llvm_unreachable("not yet implemented") 22 23 static void genOMP(Fortran::lower::AbstractConverter &absConv, 24 Fortran::lower::pft::Evaluation &eval, 25 const Fortran::parser::OpenMPSimpleStandaloneConstruct 26 &simpleStandaloneConstruct) { 27 const auto &directive = 28 std::get<Fortran::parser::OmpSimpleStandaloneDirective>( 29 simpleStandaloneConstruct.t); 30 switch (directive.v) { 31 default: 32 break; 33 case llvm::omp::Directive::OMPD_barrier: 34 absConv.getFirOpBuilder().create<mlir::omp::BarrierOp>( 35 absConv.getCurrentLocation()); 36 break; 37 case llvm::omp::Directive::OMPD_taskwait: 38 absConv.getFirOpBuilder().create<mlir::omp::TaskwaitOp>( 39 absConv.getCurrentLocation()); 40 break; 41 case llvm::omp::Directive::OMPD_taskyield: 42 absConv.getFirOpBuilder().create<mlir::omp::TaskyieldOp>( 43 absConv.getCurrentLocation()); 44 break; 45 case llvm::omp::Directive::OMPD_target_enter_data: 46 TODO(); 47 case llvm::omp::Directive::OMPD_target_exit_data: 48 TODO(); 49 case llvm::omp::Directive::OMPD_target_update: 50 TODO(); 51 case llvm::omp::Directive::OMPD_ordered: 52 TODO(); 53 } 54 } 55 56 static void 57 genOMP(Fortran::lower::AbstractConverter &absConv, 58 Fortran::lower::pft::Evaluation &eval, 59 const Fortran::parser::OpenMPStandaloneConstruct &standaloneConstruct) { 60 std::visit( 61 Fortran::common::visitors{ 62 [&](const Fortran::parser::OpenMPSimpleStandaloneConstruct 63 &simpleStandaloneConstruct) { 64 genOMP(absConv, eval, simpleStandaloneConstruct); 65 }, 66 [&](const Fortran::parser::OpenMPFlushConstruct &flushConstruct) { 67 TODO(); 68 }, 69 [&](const Fortran::parser::OpenMPCancelConstruct &cancelConstruct) { 70 TODO(); 71 }, 72 [&](const Fortran::parser::OpenMPCancellationPointConstruct 73 &cancellationPointConstruct) { TODO(); }, 74 }, 75 standaloneConstruct.u); 76 } 77 78 static void 79 genOMP(Fortran::lower::AbstractConverter &absConv, 80 Fortran::lower::pft::Evaluation &eval, 81 const Fortran::parser::OpenMPBlockConstruct &blockConstruct) { 82 const auto &blockDirective = 83 std::get<Fortran::parser::OmpBeginBlockDirective>(blockConstruct.t); 84 const auto ¶llelDirective = 85 std::get<Fortran::parser::OmpBlockDirective>(blockDirective.t); 86 if (parallelDirective.v == llvm::omp::OMPD_parallel) { 87 auto &firOpBuilder = absConv.getFirOpBuilder(); 88 auto currentLocation = absConv.getCurrentLocation(); 89 auto insertPt = firOpBuilder.saveInsertionPoint(); 90 llvm::ArrayRef<mlir::Type> argTy; 91 mlir::ValueRange range; 92 llvm::SmallVector<int32_t, 6> operandSegmentSizes(6 /*Size=*/, 93 0 /*Value=*/); 94 // create and insert the operation. 95 auto parallelOp = firOpBuilder.create<mlir::omp::ParallelOp>( 96 currentLocation, argTy, range); 97 parallelOp.setAttr(mlir::omp::ParallelOp::getOperandSegmentSizeAttr(), 98 firOpBuilder.getI32VectorAttr(operandSegmentSizes)); 99 parallelOp.getRegion().push_back(new Block{}); 100 auto &block = parallelOp.getRegion().back(); 101 firOpBuilder.setInsertionPointToStart(&block); 102 // ensure the block is well-formed. 103 firOpBuilder.create<mlir::omp::TerminatorOp>(currentLocation); 104 firOpBuilder.restoreInsertionPoint(insertPt); 105 } 106 } 107 108 void Fortran::lower::genOpenMPConstruct( 109 Fortran::lower::AbstractConverter &absConv, 110 Fortran::lower::pft::Evaluation &eval, 111 const Fortran::parser::OpenMPConstruct &ompConstruct) { 112 113 std::visit( 114 common::visitors{ 115 [&](const Fortran::parser::OpenMPStandaloneConstruct 116 &standaloneConstruct) { 117 genOMP(absConv, eval, standaloneConstruct); 118 }, 119 [&](const Fortran::parser::OpenMPSectionsConstruct 120 §ionsConstruct) { TODO(); }, 121 [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { 122 TODO(); 123 }, 124 [&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) { 125 genOMP(absConv, eval, blockConstruct); 126 }, 127 [&](const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) { 128 TODO(); 129 }, 130 [&](const Fortran::parser::OpenMPCriticalConstruct 131 &criticalConstruct) { TODO(); }, 132 }, 133 ompConstruct.u); 134 } 135 136 void Fortran::lower::genOpenMPEndLoop( 137 Fortran::lower::AbstractConverter &, Fortran::lower::pft::Evaluation &, 138 const Fortran::parser::OmpEndLoopDirective &) { 139 TODO(); 140 } 141