//===-- SymbolMap.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Pretty printers for symbol boxes, etc. // //===----------------------------------------------------------------------===// #include "flang/Lower/SymbolMap.h" #include "flang/Optimizer/Builder/Todo.h" #include "mlir/IR/BuiltinTypes.h" #include "llvm/Support/Debug.h" #include #define DEBUG_TYPE "flang-lower-symbol-map" void Fortran::lower::SymMap::addSymbol(Fortran::semantics::SymbolRef sym, const fir::ExtendedValue &exv, bool force) { exv.match([&](const fir::UnboxedValue &v) { addSymbol(sym, v, force); }, [&](const fir::CharBoxValue &v) { makeSym(sym, v, force); }, [&](const fir::ArrayBoxValue &v) { makeSym(sym, v, force); }, [&](const fir::CharArrayBoxValue &v) { makeSym(sym, v, force); }, [&](const fir::BoxValue &v) { makeSym(sym, v, force); }, [&](const fir::MutableBoxValue &v) { makeSym(sym, v, force); }, [&](const fir::PolymorphicValue &v) { makeSym(sym, v, force); }, [](auto) { llvm::report_fatal_error("value not added to symbol table"); }); } Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupSymbol(Fortran::semantics::SymbolRef symRef) { auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate(); for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend(); jmap != jend; ++jmap) { auto iter = jmap->find(sym); if (iter != jmap->end()) return iter->second; } return SymbolBox::None{}; } Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol( Fortran::semantics::SymbolRef symRef) { auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate(); auto &map = symbolMapStack.back(); auto iter = map.find(sym); if (iter != map.end()) return iter->second; return SymbolBox::None{}; } /// Skip one level when looking up the symbol. The use case is such as looking /// up the host variable symbol box by skipping the associated level in /// host-association in OpenMP code. Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupOneLevelUpSymbol( Fortran::semantics::SymbolRef symRef) { auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate(); auto jmap = symbolMapStack.rbegin(); auto jend = symbolMapStack.rend(); if (jmap == jend) return SymbolBox::None{}; // Skip one level in symbol map stack. for (++jmap; jmap != jend; ++jmap) { auto iter = jmap->find(sym); if (iter != jmap->end()) return iter->second; } return SymbolBox::None{}; } mlir::Value Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) { for (auto [marker, binding] : llvm::reverse(impliedDoStack)) if (var == marker) return binding; return {}; } llvm::raw_ostream & Fortran::lower::operator<<(llvm::raw_ostream &os, const Fortran::lower::SymbolBox &symBox) { symBox.match( [&](const Fortran::lower::SymbolBox::None &box) { os << "** symbol not properly mapped **\n"; }, [&](const Fortran::lower::SymbolBox::Intrinsic &val) { os << val.getAddr() << '\n'; }, [&](const auto &box) { os << box << '\n'; }); return os; } llvm::raw_ostream & Fortran::lower::operator<<(llvm::raw_ostream &os, const Fortran::lower::SymMap &symMap) { os << "Symbol map:\n"; for (auto i : llvm::enumerate(symMap.symbolMapStack)) { os << " level " << i.index() << "<{\n"; for (auto iter : i.value()) { os << " symbol @" << static_cast(iter.first) << " [" << *iter.first << "] ->\n "; os << iter.second; } os << " }>\n"; } return os; }