1 //===-- Utils..cpp ----------------------------------------------*- C++ -*-===// 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 "Utils.h" 14 #include "Clauses.h" 15 16 #include <flang/Lower/AbstractConverter.h> 17 #include <flang/Lower/ConvertType.h> 18 #include <flang/Optimizer/Builder/FIRBuilder.h> 19 #include <flang/Parser/parse-tree.h> 20 #include <flang/Parser/tools.h> 21 #include <flang/Semantics/tools.h> 22 #include <llvm/Support/CommandLine.h> 23 24 llvm::cl::opt<bool> treatIndexAsSection( 25 "openmp-treat-index-as-section", 26 llvm::cl::desc("In the OpenMP data clauses treat `a(N)` as `a(N:N)`."), 27 llvm::cl::init(true)); 28 29 llvm::cl::opt<bool> enableDelayedPrivatization( 30 "openmp-enable-delayed-privatization", 31 llvm::cl::desc( 32 "Emit `[first]private` variables as clauses on the MLIR ops."), 33 llvm::cl::init(false)); 34 35 namespace Fortran { 36 namespace lower { 37 namespace omp { 38 39 void genObjectList(const ObjectList &objects, 40 Fortran::lower::AbstractConverter &converter, 41 llvm::SmallVectorImpl<mlir::Value> &operands) { 42 for (const Object &object : objects) { 43 const Fortran::semantics::Symbol *sym = object.id(); 44 assert(sym && "Expected Symbol"); 45 if (mlir::Value variable = converter.getSymbolAddress(*sym)) { 46 operands.push_back(variable); 47 } else if (const auto *details = 48 sym->detailsIf<Fortran::semantics::HostAssocDetails>()) { 49 operands.push_back(converter.getSymbolAddress(details->symbol())); 50 converter.copySymbolBinding(details->symbol(), *sym); 51 } 52 } 53 } 54 55 void genObjectList2(const Fortran::parser::OmpObjectList &objectList, 56 Fortran::lower::AbstractConverter &converter, 57 llvm::SmallVectorImpl<mlir::Value> &operands) { 58 auto addOperands = [&](Fortran::lower::SymbolRef sym) { 59 const mlir::Value variable = converter.getSymbolAddress(sym); 60 if (variable) { 61 operands.push_back(variable); 62 } else if (const auto *details = 63 sym->detailsIf<Fortran::semantics::HostAssocDetails>()) { 64 operands.push_back(converter.getSymbolAddress(details->symbol())); 65 converter.copySymbolBinding(details->symbol(), sym); 66 } 67 }; 68 for (const Fortran::parser::OmpObject &ompObject : objectList.v) { 69 Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); 70 addOperands(*sym); 71 } 72 } 73 74 mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, 75 std::size_t loopVarTypeSize) { 76 // OpenMP runtime requires 32-bit or 64-bit loop variables. 77 loopVarTypeSize = loopVarTypeSize * 8; 78 if (loopVarTypeSize < 32) { 79 loopVarTypeSize = 32; 80 } else if (loopVarTypeSize > 64) { 81 loopVarTypeSize = 64; 82 mlir::emitWarning(converter.getCurrentLocation(), 83 "OpenMP loop iteration variable cannot have more than 64 " 84 "bits size and will be narrowed into 64 bits."); 85 } 86 assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && 87 "OpenMP loop iteration variable size must be transformed into 32-bit " 88 "or 64-bit"); 89 return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); 90 } 91 92 void gatherFuncAndVarSyms( 93 const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, 94 llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) { 95 for (const Object &object : objects) 96 symbolAndClause.emplace_back(clause, *object.id()); 97 } 98 99 Fortran::semantics::Symbol * 100 getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { 101 Fortran::semantics::Symbol *sym = nullptr; 102 std::visit( 103 Fortran::common::visitors{ 104 [&](const Fortran::parser::Designator &designator) { 105 if (auto *arrayEle = 106 Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( 107 designator)) { 108 sym = GetFirstName(arrayEle->base).symbol; 109 } else if (auto *structComp = Fortran::parser::Unwrap< 110 Fortran::parser::StructureComponent>(designator)) { 111 sym = structComp->component.symbol; 112 } else if (const Fortran::parser::Name *name = 113 Fortran::semantics::getDesignatorNameIfDataRef( 114 designator)) { 115 sym = name->symbol; 116 } 117 }, 118 [&](const Fortran::parser::Name &name) { sym = name.symbol; }}, 119 ompObject.u); 120 return sym; 121 } 122 123 } // namespace omp 124 } // namespace lower 125 } // namespace Fortran 126