145 lines · cpp
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-exception6//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 21void 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 36Fortran::lower::SymbolBox37Fortran::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 48const Fortran::semantics::Symbol *49Fortran::lower::SymMap::lookupSymbolByName(llvm::StringRef symName) {50 for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();51 jmap != jend; ++jmap)52 for (auto const &[sym, symBox] : *jmap)53 if (sym->name().ToString() == symName)54 return sym;55 return nullptr;56}57 58Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol(59 Fortran::semantics::SymbolRef symRef) {60 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();61 auto &map = symbolMapStack.back();62 auto iter = map.find(sym);63 if (iter != map.end())64 return iter->second;65 return SymbolBox::None{};66}67 68/// Skip one level when looking up the symbol. The use case is such as looking69/// up the host variable symbol box by skipping the associated level in70/// host-association in OpenMP code.71Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupOneLevelUpSymbol(72 Fortran::semantics::SymbolRef symRef) {73 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();74 auto jmap = symbolMapStack.rbegin();75 auto jend = symbolMapStack.rend();76 if (jmap == jend)77 return SymbolBox::None{};78 // Skip one level in symbol map stack.79 for (++jmap; jmap != jend; ++jmap) {80 auto iter = jmap->find(sym);81 if (iter != jmap->end())82 return iter->second;83 }84 return SymbolBox::None{};85}86 87mlir::Value88Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {89 for (auto [marker, binding] : llvm::reverse(impliedDoStack))90 if (var == marker)91 return binding;92 return {};93}94 95void Fortran::lower::SymMap::registerStorage(96 semantics::SymbolRef symRef, Fortran::lower::SymMap::StorageDesc storage) {97 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();98 assert(storage.first && "registerting storage without an address");99 storageMapStack.back().insert_or_assign(sym, std::move(storage));100}101 102Fortran::lower::SymMap::StorageDesc103Fortran::lower::SymMap::lookupStorage(Fortran::semantics::SymbolRef symRef) {104 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();105 auto &map = storageMapStack.back();106 auto iter = map.find(sym);107 if (iter != map.end())108 return iter->second;109 return {nullptr, 0};110}111 112void Fortran::lower::SymbolBox::dump() const { llvm::errs() << *this << '\n'; }113 114void Fortran::lower::SymMap::dump() const { llvm::errs() << *this << '\n'; }115 116llvm::raw_ostream &117Fortran::lower::operator<<(llvm::raw_ostream &os,118 const Fortran::lower::SymbolBox &symBox) {119 symBox.match(120 [&](const Fortran::lower::SymbolBox::None &box) {121 os << "** symbol not properly mapped **\n";122 },123 [&](const Fortran::lower::SymbolBox::Intrinsic &val) {124 os << val.getAddr() << '\n';125 },126 [&](const auto &box) { os << box << '\n'; });127 return os;128}129 130llvm::raw_ostream &131Fortran::lower::operator<<(llvm::raw_ostream &os,132 const Fortran::lower::SymMap &symMap) {133 os << "Symbol map:\n";134 for (auto i : llvm::enumerate(symMap.symbolMapStack)) {135 os << " level " << i.index() << "<{\n";136 for (auto iter : i.value()) {137 os << " symbol @" << static_cast<const void *>(iter.first) << " ["138 << *iter.first << "] ->\n ";139 os << iter.second;140 }141 os << " }>\n";142 }143 return os;144}145