| //===-- Utils..cpp ----------------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "Utils.h" |
| #include "Clauses.h" |
| |
| #include <flang/Lower/AbstractConverter.h> |
| #include <flang/Lower/ConvertType.h> |
| #include <flang/Optimizer/Builder/FIRBuilder.h> |
| #include <flang/Parser/parse-tree.h> |
| #include <flang/Parser/tools.h> |
| #include <flang/Semantics/tools.h> |
| #include <llvm/Support/CommandLine.h> |
| |
| llvm::cl::opt<bool> treatIndexAsSection( |
| "openmp-treat-index-as-section", |
| llvm::cl::desc("In the OpenMP data clauses treat `a(N)` as `a(N:N)`."), |
| llvm::cl::init(true)); |
| |
| llvm::cl::opt<bool> enableDelayedPrivatization( |
| "openmp-enable-delayed-privatization", |
| llvm::cl::desc( |
| "Emit `[first]private` variables as clauses on the MLIR ops."), |
| llvm::cl::init(false)); |
| |
| namespace Fortran { |
| namespace lower { |
| namespace omp { |
| |
| int64_t getCollapseValue(const List<Clause> &clauses) { |
| auto iter = llvm::find_if(clauses, [](const Clause &clause) { |
| return clause.id == llvm::omp::Clause::OMPC_collapse; |
| }); |
| if (iter != clauses.end()) { |
| const auto &collapse = std::get<clause::Collapse>(iter->u); |
| return evaluate::ToInt64(collapse.v).value(); |
| } |
| return 1; |
| } |
| |
| void genObjectList(const ObjectList &objects, |
| Fortran::lower::AbstractConverter &converter, |
| llvm::SmallVectorImpl<mlir::Value> &operands) { |
| for (const Object &object : objects) { |
| const Fortran::semantics::Symbol *sym = object.id(); |
| assert(sym && "Expected Symbol"); |
| if (mlir::Value variable = converter.getSymbolAddress(*sym)) { |
| operands.push_back(variable); |
| } else if (const auto *details = |
| sym->detailsIf<Fortran::semantics::HostAssocDetails>()) { |
| operands.push_back(converter.getSymbolAddress(details->symbol())); |
| converter.copySymbolBinding(details->symbol(), *sym); |
| } |
| } |
| } |
| |
| mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, |
| std::size_t loopVarTypeSize) { |
| // OpenMP runtime requires 32-bit or 64-bit loop variables. |
| loopVarTypeSize = loopVarTypeSize * 8; |
| if (loopVarTypeSize < 32) { |
| loopVarTypeSize = 32; |
| } else if (loopVarTypeSize > 64) { |
| loopVarTypeSize = 64; |
| mlir::emitWarning(converter.getCurrentLocation(), |
| "OpenMP loop iteration variable cannot have more than 64 " |
| "bits size and will be narrowed into 64 bits."); |
| } |
| assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && |
| "OpenMP loop iteration variable size must be transformed into 32-bit " |
| "or 64-bit"); |
| return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); |
| } |
| |
| void gatherFuncAndVarSyms( |
| const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, |
| llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) { |
| for (const Object &object : objects) |
| symbolAndClause.emplace_back(clause, *object.id()); |
| } |
| |
| Fortran::semantics::Symbol * |
| getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { |
| Fortran::semantics::Symbol *sym = nullptr; |
| std::visit( |
| Fortran::common::visitors{ |
| [&](const Fortran::parser::Designator &designator) { |
| if (auto *arrayEle = |
| Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( |
| designator)) { |
| sym = GetFirstName(arrayEle->base).symbol; |
| } else if (auto *structComp = Fortran::parser::Unwrap< |
| Fortran::parser::StructureComponent>(designator)) { |
| sym = structComp->component.symbol; |
| } else if (const Fortran::parser::Name *name = |
| Fortran::semantics::getDesignatorNameIfDataRef( |
| designator)) { |
| sym = name->symbol; |
| } |
| }, |
| [&](const Fortran::parser::Name &name) { sym = name.symbol; }}, |
| ompObject.u); |
| return sym; |
| } |
| |
| } // namespace omp |
| } // namespace lower |
| } // namespace Fortran |