//===-- 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 #include #include #include #include #include #include #include llvm::cl::opt 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 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 &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(iter->u); return evaluate::ToInt64(collapse.v).value(); } return 1; } uint32_t getOpenMPVersion(mlir::ModuleOp mod) { if (mlir::Attribute verAttr = mod->getAttr("omp.version")) return llvm::cast(verAttr).getVersion(); llvm_unreachable("Expecting OpenMP version attribute in module"); } void genObjectList(const ObjectList &objects, Fortran::lower::AbstractConverter &converter, llvm::SmallVectorImpl &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()) { 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); } Fortran::semantics::Symbol * getIterationVariableSymbol(const Fortran::lower::pft::Evaluation &eval) { return eval.visit(Fortran::common::visitors{ [&](const Fortran::parser::DoConstruct &doLoop) { if (const auto &maybeCtrl = doLoop.GetLoopControl()) { using LoopControl = Fortran::parser::LoopControl; if (auto *bounds = std::get_if(&maybeCtrl->u)) { static_assert( std::is_same_vname), Fortran::parser::Scalar>); return bounds->name.thing.symbol; } } return static_cast(nullptr); }, [](auto &&) { return static_cast(nullptr); }, }); } void gatherFuncAndVarSyms( const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, llvm::SmallVectorImpl &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( 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