13#ifndef FORTRAN_LOWER_SUPPORT_UTILS_H
14#define FORTRAN_LOWER_SUPPORT_UTILS_H
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/StringRef.h"
35 return {cb.begin(), cb.size()};
40const A &removeIndirection(
const A &a) {
51 return Fortran::evaluate::AsGenericExpr(Fortran::common::Clone(x));
54template <Fortran::common::TypeCategory FROM>
59 return toEvExpr(x.left());
71 Fortran::common::TypeCategory::Integer, 8>> &x) {
72 return Fortran::common::visit(
73 [](
const auto &v) {
return ignoreEvConvert(v); }, x.u);
79A flatZip(
const A &container1,
const A &container2) {
80 assert(container1.size() == container2.size());
82 for (
auto [e1, e2] : llvm::zip(container1, container2)) {
83 result.emplace_back(e1);
84 result.emplace_back(e2);
110 return static_cast<unsigned>(
reinterpret_cast<std::intptr_t
>(&x));
112 template <
typename A,
bool COPY>
114 return getHashValue(x.value());
116 template <
typename A>
117 static unsigned getHashValue(
const std::optional<A> &x) {
119 return getHashValue(x.value());
123 return Fortran::common::visit(
124 [&](
const auto &v) {
return getHashValue(v); }, x.u);
127 return getHashValue(x.lower()) - getHashValue(x.upper()) * 5u -
128 getHashValue(x.stride()) * 11u;
131 return getHashValue(x.base()) * 83u - getHashValue(x.GetLastSymbol());
136 subs -= getHashValue(v);
137 return getHashValue(x.base()) * 89u - subs;
142 subs -= getHashValue(v);
143 unsigned cosubs = 3u;
146 cosubs -= getHashValue(v);
149 syms += getHashValue(v);
150 return syms * 97u - subs - cosubs + getHashValue(x.stat()) + 257u +
151 getHashValue(x.team());
155 return getHashValue(x.GetFirstSymbol()) * 11u;
156 return getHashValue(x.GetComponent()) * 13u;
159 return Fortran::common::visit(
160 [&](
const auto &v) {
return getHashValue(v); }, x.u);
163 return getHashValue(x.complex()) -
static_cast<unsigned>(x.part());
165 template <Fortran::common::TypeCategory TC1,
int KIND,
166 Fortran::common::TypeCategory TC2>
167 static unsigned getHashValue(
170 return getHashValue(x.left()) - (
static_cast<unsigned>(TC1) + 2u) -
171 (
static_cast<unsigned>(KIND) + 5u);
176 return getHashValue(x.left()) -
177 (
static_cast<unsigned>(x.isImaginaryPart) + 1u) * 3u;
179 template <
typename T>
181 return getHashValue(x.left()) * 17u;
183 template <Fortran::common::TypeCategory TC,
int KIND>
184 static unsigned getHashValue(
186 return getHashValue(x.left()) - (
static_cast<unsigned>(TC) + 5u) -
187 (
static_cast<unsigned>(KIND) + 7u);
189 template <Fortran::common::TypeCategory TC,
int KIND>
190 static unsigned getHashValue(
192 return (getHashValue(x.left()) + getHashValue(x.right())) * 23u +
193 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
195 template <Fortran::common::TypeCategory TC,
int KIND>
196 static unsigned getHashValue(
198 return (getHashValue(x.left()) - getHashValue(x.right())) * 19u +
199 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
201 template <Fortran::common::TypeCategory TC,
int KIND>
202 static unsigned getHashValue(
204 return (getHashValue(x.left()) + getHashValue(x.right())) * 29u +
205 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
207 template <Fortran::common::TypeCategory TC,
int KIND>
208 static unsigned getHashValue(
210 return (getHashValue(x.left()) - getHashValue(x.right())) * 31u +
211 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
213 template <Fortran::common::TypeCategory TC,
int KIND>
214 static unsigned getHashValue(
216 return (getHashValue(x.left()) - getHashValue(x.right())) * 37u +
217 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
219 template <Fortran::common::TypeCategory TC,
int KIND>
220 static unsigned getHashValue(
222 return (getHashValue(x.left()) + getHashValue(x.right())) * 41u +
223 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND) +
224 static_cast<unsigned>(x.ordering) * 7u;
226 template <Fortran::common::TypeCategory TC,
int KIND>
227 static unsigned getHashValue(
230 return (getHashValue(x.left()) - getHashValue(x.right())) * 43u +
231 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND);
236 return (getHashValue(x.left()) - getHashValue(x.right())) * 47u +
237 static_cast<unsigned>(KIND);
241 return (getHashValue(x.left()) - getHashValue(x.right())) * 53u +
242 static_cast<unsigned>(KIND);
246 return (getHashValue(x.left()) - getHashValue(x.right())) * 59u +
247 static_cast<unsigned>(KIND);
250 return getHashValue(sym.get());
254 Fortran::common::visit(
255 [&](
const auto &p) {
return getHashValue(p); }, x.parent()) -
256 getHashValue(x.lower()) - (getHashValue(x.lower()) + 1u);
259 getHashValue(
const Fortran::evaluate::StaticDataObject::Pointer &x) {
260 return llvm::hash_value(x->name());
263 return llvm::hash_value(x.name);
265 template <
typename A>
272 return getHashValue(*sym);
273 return getHashValue(*x.UnwrapExpr());
277 return Fortran::common::visit(
278 [&](
const auto &v) {
return getHashValue(v); }, x.u);
282 for (
const std::optional<Fortran::evaluate::ActualArgument> &v :
284 args -= getHashValue(v);
285 return getHashValue(x.proc()) * 101u - args;
287 template <
typename A>
294 return llvm::hash_value(toStringRef(x.name).str()) * 131u;
297 return getHashValue(x.base()) * 137u - getHashValue(x.parameter()) * 3u;
300 return getHashValue(x.base()) * 139u -
301 static_cast<unsigned>(x.field()) * 13u +
302 static_cast<unsigned>(x.dimension());
311 return getHashValue(x.left()) * 61u +
static_cast<unsigned>(KIND);
316 unsigned result = getHashValue(x.left()) + getHashValue(x.right());
317 return result * 67u +
static_cast<unsigned>(x.logicalOperator) * 5u;
319 template <Fortran::common::TypeCategory TC,
int KIND>
320 static unsigned getHashValue(
323 return (getHashValue(x.left()) + getHashValue(x.right())) * 71u +
324 static_cast<unsigned>(TC) +
static_cast<unsigned>(KIND) +
325 static_cast<unsigned>(x.opr) * 11u;
327 template <
typename A>
329 return Fortran::common::visit(
330 [&](
const auto &v) {
return getHashValue(v); }, x.u);
332 static unsigned getHashValue(
334 return Fortran::common::visit(
335 [&](
const auto &v) {
return getHashValue(v); }, x.u);
337 template <
typename A>
339 return Fortran::common::visit(
340 [&](
const auto &v) {
return getHashValue(v); }, x.u);
344 getHashValue(
const Fortran::evaluate::value::Integer<BITS> &x) {
345 return static_cast<unsigned>(x.ToSInt());
360 return isEqual(&x, &y);
366 template <
typename A,
bool COPY>
369 return isEqual(x.value(), y.value());
371 template <
typename A>
372 static bool isEqual(
const std::optional<A> &x,
const std::optional<A> &y) {
373 if (x.has_value() && y.has_value())
374 return isEqual(x.value(), y.value());
375 return !x.has_value() && !y.has_value();
377 template <
typename A>
378 static bool isEqual(
const std::vector<A> &x,
const std::vector<A> &y) {
379 if (x.size() != y.size())
381 const std::size_t size = x.size();
382 for (std::remove_const_t<
decltype(size)> i = 0; i < size; ++i)
383 if (!isEqual(x[i], y[i]))
389 return Fortran::common::visit(
390 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
394 return isEqual(x.lower(), y.lower()) && isEqual(x.upper(), y.upper()) &&
395 isEqual(x.stride(), y.stride());
399 return isEqual(x.base(), y.base()) &&
400 isEqual(x.GetLastSymbol(), y.GetLastSymbol());
404 return isEqual(x.base(), y.base()) && isEqual(x.subscript(), y.subscript());
408 return isEqual(x.base(), y.base()) &&
409 isEqual(x.subscript(), y.subscript()) &&
410 isEqual(x.cosubscript(), y.cosubscript()) &&
411 isEqual(x.stat(), y.stat()) && isEqual(x.team(), y.team());
415 if (x.IsSymbol() && y.IsSymbol())
416 return isEqual(x.GetFirstSymbol(), y.GetFirstSymbol());
417 return !x.IsSymbol() && !y.IsSymbol() &&
418 isEqual(x.GetComponent(), y.GetComponent());
422 return Fortran::common::visit(
423 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
427 return isEqual(x.complex(), y.complex()) && x.part() == y.part();
429 template <
typename A, Fortran::common::TypeCategory TC2>
432 return isEqual(x.left(), y.left());
437 return isEqual(x.left(), y.left()) &&
438 x.isImaginaryPart == y.isImaginaryPart;
440 template <
typename T>
443 return isEqual(x.left(), y.left());
445 template <
typename A>
448 return isEqual(x.left(), y.left());
450 template <
typename A>
451 static bool isBinaryEqual(
const A &x,
const A &y) {
452 return isEqual(x.left(), y.left()) && isEqual(x.right(), y.right());
454 template <
typename A>
457 return isBinaryEqual(x, y);
459 template <
typename A>
462 return isBinaryEqual(x, y);
464 template <
typename A>
467 return isBinaryEqual(x, y);
469 template <
typename A>
472 return isBinaryEqual(x, y);
474 template <
typename A>
477 return isBinaryEqual(x, y);
479 template <
typename A>
482 return isBinaryEqual(x, y);
484 template <
typename A>
487 return isBinaryEqual(x, y);
492 return isBinaryEqual(x, y);
497 return isBinaryEqual(x, y);
502 return isBinaryEqual(x, y);
506 return isEqual(x.get(), y.get());
510 return Fortran::common::visit(
511 [&](
const auto &p,
const auto &q) {
return isEqual(p, q); },
512 x.parent(), y.parent()) &&
513 isEqual(x.lower(), y.lower()) && isEqual(x.upper(), y.upper());
515 static bool isEqual(
const Fortran::evaluate::StaticDataObject::Pointer &x,
516 const Fortran::evaluate::StaticDataObject::Pointer &y) {
517 return x->name() == y->name();
521 return x.name == y.name;
523 template <
typename A>
532 return isEqual(*xs, *ys);
535 return !y.GetAssumedTypeDummy() &&
536 isEqual(*x.UnwrapExpr(), *y.UnwrapExpr());
540 return Fortran::common::visit(
541 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
545 return isEqual(x.proc(), y.proc()) && isEqual(x.arguments(), y.arguments());
547 template <
typename A>
550 llvm::report_fatal_error(
"not implemented");
554 return toStringRef(x.name) == toStringRef(y.name);
558 return isEqual(x.base(), y.base()) && isEqual(x.parameter(), y.parameter());
562 return isEqual(x.base(), y.base()) && x.field() == y.field() &&
563 x.dimension() == y.dimension();
567 const auto &xValues = x.values();
568 const auto &yValues = y.values();
569 if (xValues.size() != yValues.size())
571 if (x.derivedTypeSpec() != y.derivedTypeSpec())
573 for (
const auto &[xSymbol, xValue] : xValues) {
574 auto yIt = yValues.find(xSymbol);
577 if (yIt == yValues.end())
579 if (!isEqual(xValue, yIt->second))
587 return isEqual(x.left(), y.left());
592 return isEqual(x.left(), y.left()) && isEqual(x.right(), y.right());
594 template <
typename A>
597 return isEqual(x.left(), y.left()) && isEqual(x.right(), y.right());
599 template <
typename A>
602 return Fortran::common::visit(
603 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
608 return Fortran::common::visit(
609 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
611 template <
typename A>
614 return Fortran::common::visit(
615 [&](
const auto &v,
const auto &w) {
return isEqual(v, w); }, x.u, y.u);
618 static bool isEqual(
const Fortran::evaluate::value::Integer<BITS> &x,
619 const Fortran::evaluate::value::Integer<BITS> &y) {
626 template <
typename A,
typename B,
627 std::enable_if_t<!std::is_same_v<A, B>,
bool> =
true>
628 static bool isEqual(
const A &,
const B &) {
634 return HashEvaluateExpr::getHashValue(*x);
652 return Fortran::lower::getHashValue(v);
656 return Fortran::lower::isEqual(lhs, rhs);
665 llvm::DenseMapInfo<const Fortran::lower::SomeExpr *>::getEmptyKey();
666 const auto *tombstone =
667 llvm::DenseMapInfo<const Fortran::lower::SomeExpr *>::getTombstoneKey();
668 if (x == empty || y == empty || x == tombstone || y == tombstone)
670 return x == y || IsEqualEvaluateExpr::isEqual(*x, *y);
Definition: indirection.h:31
Definition: expression.h:466
Definition: variable.h:208
Definition: variable.h:255
Definition: variable.h:369
Definition: variable.h:74
Definition: constant.h:141
Definition: variable.h:425
Definition: variable.h:393
Definition: variable.h:104
Definition: expression.h:656
Definition: expression.h:740
Definition: variable.h:316
Definition: variable.h:163
Definition: variable.h:139
Definition: char-block.h:28
Definition: AbstractConverter.h:59
Definition: bit-population-count.h:20
Definition: expression.h:296
Definition: expression.h:257
Definition: expression.h:357
Definition: expression.h:368
Definition: expression.h:211
Definition: variable.h:300
Definition: expression.h:317
Definition: expression.h:340
Definition: expression.h:396
Definition: expression.h:379
Definition: expression.h:310
Definition: expression.h:247
Definition: expression.h:272
Definition: expression.h:827
Definition: expression.h:229
Definition: expression.h:324
Definition: expression.h:332
Definition: expression.h:286
Definition: variable.h:194
Definition: expression.h:303