FLANG
Utils.h
1//===-- Lower/Support/Utils.h -- utilities ----------------------*- 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#ifndef FORTRAN_LOWER_SUPPORT_UTILS_H
14#define FORTRAN_LOWER_SUPPORT_UTILS_H
15
16#include "flang/Common/indirection.h"
17#include "flang/Parser/char-block.h"
18#include "flang/Semantics/tools.h"
19#include "mlir/Dialect/Arith/IR/Arith.h"
20#include "mlir/Dialect/Func/IR/FuncOps.h"
21#include "mlir/IR/BuiltinAttributes.h"
22#include "llvm/ADT/SmallSet.h"
23#include "llvm/ADT/StringRef.h"
24
25namespace Fortran::evaluate {
26class Component;
27class ArrayRef;
28} // namespace Fortran::evaluate
29
30namespace Fortran::lower {
31using SomeExpr = Fortran::evaluate::Expr<Fortran::evaluate::SomeType>;
32using ExplicitSpaceArrayBases =
33 std::variant<const semantics::Symbol *, const evaluate::Component *,
34 const evaluate::ArrayRef *>;
35// FIXME: needed for privatizeSymbol that does not belong to this header.
37class SymMap;
38} // end namespace Fortran::lower
39
40namespace fir {
41class FirOpBuilder;
42}
43
44//===----------------------------------------------------------------------===//
45// Small inline helper functions to deal with repetitive, clumsy conversions.
46//===----------------------------------------------------------------------===//
47
49inline llvm::StringRef toStringRef(const Fortran::parser::CharBlock &cb) {
50 return {cb.begin(), cb.size()};
51}
52
54template <typename A>
55const A &removeIndirection(const A &a) {
56 return a;
57}
58template <typename A>
59const A &removeIndirection(const Fortran::common::Indirection<A> &a) {
60 return a.value();
61}
62
64template <typename A>
65static Fortran::lower::SomeExpr toEvExpr(const A &x) {
66 return Fortran::evaluate::AsGenericExpr(Fortran::common::Clone(x));
67}
68
69template <Fortran::common::TypeCategory FROM>
70static Fortran::lower::SomeExpr ignoreEvConvert(
73 FROM> &x) {
74 return toEvExpr(x.left());
75}
76template <typename A>
77static Fortran::lower::SomeExpr ignoreEvConvert(const A &x) {
78 return toEvExpr(x);
79}
80
84inline Fortran::lower::SomeExpr
86 Fortran::common::TypeCategory::Integer, 8>> &x) {
87 return Fortran::common::visit(
88 [](const auto &v) { return ignoreEvConvert(v); }, x.u);
89}
90
93template <typename A>
94A flatZip(const A &container1, const A &container2) {
95 assert(container1.size() == container2.size());
96 A result;
97 for (auto [e1, e2] : llvm::zip(container1, container2)) {
98 result.emplace_back(e1);
99 result.emplace_back(e2);
100 }
101 return result;
102}
103
104namespace Fortran::lower {
105unsigned getHashValue(const Fortran::lower::SomeExpr *x);
106unsigned getHashValue(const Fortran::lower::ExplicitSpaceArrayBases &x);
107unsigned getHashValue(const Fortran::evaluate::Component *x);
108
109bool isEqual(const Fortran::lower::SomeExpr *x,
110 const Fortran::lower::SomeExpr *y);
111bool isEqual(const Fortran::lower::ExplicitSpaceArrayBases &x,
112 const Fortran::lower::ExplicitSpaceArrayBases &y);
113bool isEqual(const Fortran::evaluate::Component *x,
114 const Fortran::evaluate::Component *y);
115
116template <typename OpType, typename OperandsStructType>
117void privatizeSymbol(
118 lower::AbstractConverter &converter, fir::FirOpBuilder &firOpBuilder,
119 lower::SymMap &symTable,
120 llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
121 llvm::SmallPtrSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
122 const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps,
123 std::optional<llvm::omp::Directive> dir = std::nullopt);
124
125} // end namespace Fortran::lower
126
127// DenseMapInfo for pointers to Fortran::lower::SomeExpr.
128namespace llvm {
129template <>
130struct DenseMapInfo<const Fortran::lower::SomeExpr *> {
131 static inline const Fortran::lower::SomeExpr *getEmptyKey() {
132 return reinterpret_cast<Fortran::lower::SomeExpr *>(~0);
133 }
134 static inline const Fortran::lower::SomeExpr *getTombstoneKey() {
135 return reinterpret_cast<Fortran::lower::SomeExpr *>(~0 - 1);
136 }
137 static unsigned getHashValue(const Fortran::lower::SomeExpr *v) {
138 return Fortran::lower::getHashValue(v);
139 }
140 static bool isEqual(const Fortran::lower::SomeExpr *lhs,
141 const Fortran::lower::SomeExpr *rhs) {
142 return Fortran::lower::isEqual(lhs, rhs);
143 }
144};
145
146// DenseMapInfo for pointers to Fortran::evaluate::Component.
147template <>
148struct DenseMapInfo<const Fortran::evaluate::Component *> {
149 static inline const Fortran::evaluate::Component *getEmptyKey() {
150 return reinterpret_cast<Fortran::evaluate::Component *>(~0);
151 }
152 static inline const Fortran::evaluate::Component *getTombstoneKey() {
153 return reinterpret_cast<Fortran::evaluate::Component *>(~0 - 1);
154 }
155 static unsigned getHashValue(const Fortran::evaluate::Component *v) {
156 return Fortran::lower::getHashValue(v);
157 }
158 static bool isEqual(const Fortran::evaluate::Component *lhs,
159 const Fortran::evaluate::Component *rhs) {
160 return Fortran::lower::isEqual(lhs, rhs);
161 }
162};
163} // namespace llvm
164
165#endif // FORTRAN_LOWER_SUPPORT_UTILS_H
Definition indirection.h:31
Definition variable.h:205
Definition variable.h:73
Definition common.h:214
Definition type.h:57
Definition AbstractConverter.h:87
Definition SymbolMap.h:182
Definition char-block.h:28
Definition FIRBuilder.h:55
Definition call.h:34
Definition ParserActions.h:24
Definition bit-population-count.h:20
Definition AbstractConverter.h:37
Definition expression.h:211