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
24llvm::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(Val: true));
28
29llvm::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(Val: false));
34
35namespace Fortran {
36namespace lower {
37namespace omp {
38
39int64_t getCollapseValue(const List<Clause> &clauses) {
40 auto iter = llvm::find_if(Range: clauses, P: [](const Clause &clause) {
41 return clause.id == llvm::omp::Clause::OMPC_collapse;
42 });
43 if (iter != clauses.end()) {
44 const auto &collapse = std::get<clause::Collapse>(iter->u);
45 return evaluate::ToInt64(collapse.v).value();
46 }
47 return 1;
48}
49
50void genObjectList(const ObjectList &objects,
51 Fortran::lower::AbstractConverter &converter,
52 llvm::SmallVectorImpl<mlir::Value> &operands) {
53 for (const Object &object : objects) {
54 const Fortran::semantics::Symbol *sym = object.id();
55 assert(sym && "Expected Symbol");
56 if (mlir::Value variable = converter.getSymbolAddress(*sym)) {
57 operands.push_back(variable);
58 } else if (const auto *details =
59 sym->detailsIf<Fortran::semantics::HostAssocDetails>()) {
60 operands.push_back(converter.getSymbolAddress(details->symbol()));
61 converter.copySymbolBinding(details->symbol(), *sym);
62 }
63 }
64}
65
66mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter,
67 std::size_t loopVarTypeSize) {
68 // OpenMP runtime requires 32-bit or 64-bit loop variables.
69 loopVarTypeSize = loopVarTypeSize * 8;
70 if (loopVarTypeSize < 32) {
71 loopVarTypeSize = 32;
72 } else if (loopVarTypeSize > 64) {
73 loopVarTypeSize = 64;
74 mlir::emitWarning(converter.getCurrentLocation(),
75 "OpenMP loop iteration variable cannot have more than 64 "
76 "bits size and will be narrowed into 64 bits.");
77 }
78 assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) &&
79 "OpenMP loop iteration variable size must be transformed into 32-bit "
80 "or 64-bit");
81 return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize);
82}
83
84void gatherFuncAndVarSyms(
85 const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
86 llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) {
87 for (const Object &object : objects)
88 symbolAndClause.emplace_back(clause, *object.id());
89}
90
91Fortran::semantics::Symbol *
92getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) {
93 Fortran::semantics::Symbol *sym = nullptr;
94 std::visit(
95 Fortran::common::visitors{
96 [&](const Fortran::parser::Designator &designator) {
97 if (auto *arrayEle =
98 Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
99 designator)) {
100 sym = GetFirstName(arrayEle->base).symbol;
101 } else if (auto *structComp = Fortran::parser::Unwrap<
102 Fortran::parser::StructureComponent>(designator)) {
103 sym = structComp->component.symbol;
104 } else if (const Fortran::parser::Name *name =
105 Fortran::semantics::getDesignatorNameIfDataRef(
106 designator)) {
107 sym = name->symbol;
108 }
109 },
110 [&](const Fortran::parser::Name &name) { sym = name.symbol; }},
111 ompObject.u);
112 return sym;
113}
114
115} // namespace omp
116} // namespace lower
117} // namespace Fortran
118

source code of flang/lib/Lower/OpenMP/Utils.cpp