xref: /llvm-project/flang/lib/Lower/SymbolMap.cpp (revision 335b3990ef9115e3b20eb9dfa32393a7fdfde4e3)
1 //===-- SymbolMap.cpp -----------------------------------------------------===//
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 // Pretty printers for symbol boxes, etc.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "flang/Lower/SymbolMap.h"
14 #include "flang/Optimizer/Builder/Todo.h"
15 #include "mlir/IR/BuiltinTypes.h"
16 #include "llvm/Support/Debug.h"
17 #include <optional>
18 
19 #define DEBUG_TYPE "flang-lower-symbol-map"
20 
addSymbol(Fortran::semantics::SymbolRef sym,const fir::ExtendedValue & exv,bool force)21 void Fortran::lower::SymMap::addSymbol(Fortran::semantics::SymbolRef sym,
22                                        const fir::ExtendedValue &exv,
23                                        bool force) {
24   exv.match([&](const fir::UnboxedValue &v) { addSymbol(sym, v, force); },
25             [&](const fir::CharBoxValue &v) { makeSym(sym, v, force); },
26             [&](const fir::ArrayBoxValue &v) { makeSym(sym, v, force); },
27             [&](const fir::CharArrayBoxValue &v) { makeSym(sym, v, force); },
28             [&](const fir::BoxValue &v) { makeSym(sym, v, force); },
29             [&](const fir::MutableBoxValue &v) { makeSym(sym, v, force); },
30             [&](const fir::PolymorphicValue &v) { makeSym(sym, v, force); },
31             [](auto) {
32               llvm::report_fatal_error("value not added to symbol table");
33             });
34 }
35 
36 Fortran::lower::SymbolBox
lookupSymbol(Fortran::semantics::SymbolRef symRef)37 Fortran::lower::SymMap::lookupSymbol(Fortran::semantics::SymbolRef symRef) {
38   auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
39   for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
40        jmap != jend; ++jmap) {
41     auto iter = jmap->find(sym);
42     if (iter != jmap->end())
43       return iter->second;
44   }
45   return SymbolBox::None{};
46 }
47 
shallowLookupSymbol(Fortran::semantics::SymbolRef symRef)48 Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol(
49     Fortran::semantics::SymbolRef symRef) {
50   auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
51   auto &map = symbolMapStack.back();
52   auto iter = map.find(sym);
53   if (iter != map.end())
54     return iter->second;
55   return SymbolBox::None{};
56 }
57 
58 /// Skip one level when looking up the symbol. The use case is such as looking
59 /// up the host variable symbol box by skipping the associated level in
60 /// host-association in OpenMP code.
lookupOneLevelUpSymbol(Fortran::semantics::SymbolRef symRef)61 Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupOneLevelUpSymbol(
62     Fortran::semantics::SymbolRef symRef) {
63   auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
64   auto jmap = symbolMapStack.rbegin();
65   auto jend = symbolMapStack.rend();
66   if (jmap == jend)
67     return SymbolBox::None{};
68   // Skip one level in symbol map stack.
69   for (++jmap; jmap != jend; ++jmap) {
70     auto iter = jmap->find(sym);
71     if (iter != jmap->end())
72       return iter->second;
73   }
74   return SymbolBox::None{};
75 }
76 
77 mlir::Value
lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var)78 Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
79   for (auto [marker, binding] : llvm::reverse(impliedDoStack))
80     if (var == marker)
81       return binding;
82   return {};
83 }
84 
85 llvm::raw_ostream &
operator <<(llvm::raw_ostream & os,const Fortran::lower::SymbolBox & symBox)86 Fortran::lower::operator<<(llvm::raw_ostream &os,
87                            const Fortran::lower::SymbolBox &symBox) {
88   symBox.match(
89       [&](const Fortran::lower::SymbolBox::None &box) {
90         os << "** symbol not properly mapped **\n";
91       },
92       [&](const Fortran::lower::SymbolBox::Intrinsic &val) {
93         os << val.getAddr() << '\n';
94       },
95       [&](const auto &box) { os << box << '\n'; });
96   return os;
97 }
98 
99 llvm::raw_ostream &
operator <<(llvm::raw_ostream & os,const Fortran::lower::SymMap & symMap)100 Fortran::lower::operator<<(llvm::raw_ostream &os,
101                            const Fortran::lower::SymMap &symMap) {
102   os << "Symbol map:\n";
103   for (auto i : llvm::enumerate(symMap.symbolMapStack)) {
104     os << " level " << i.index() << "<{\n";
105     for (auto iter : i.value()) {
106       os << "  symbol @" << static_cast<const void *>(iter.first) << " ["
107          << *iter.first << "] ->\n    ";
108       os << iter.second;
109     }
110     os << " }>\n";
111   }
112   return os;
113 }
114