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(Val: 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(Val: false)); |
34 | |
35 | namespace Fortran { |
36 | namespace lower { |
37 | namespace omp { |
38 | |
39 | int64_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 | |
50 | void 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 | |
66 | mlir::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 | |
84 | void 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 | |
91 | Fortran::semantics::Symbol * |
92 | getOmpObjectSymbol(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 | |