brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · 011021c Raw
418 lines · cpp
1//===-- InternalNames.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// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Optimizer/Support/InternalNames.h"14#include "flang/Optimizer/Dialect/FIRType.h"15#include "mlir/IR/BuiltinTypes.h"16#include "mlir/IR/Diagnostics.h"17#include "llvm/Support/CommandLine.h"18#include <optional>19#include <regex>20 21static llvm::cl::opt<std::string> mainEntryName(22    "main-entry-name",23    llvm::cl::desc("override the name of the default PROGRAM entry (may be "24                   "helpful for using other runtimes)"));25 26constexpr std::int64_t badValue = -1;27 28inline std::string prefix() { return "_Q"; }29 30/// Generate a mangling prefix from module, submodule, procedure, and31/// statement function names, plus an (innermost) block scope id.32static std::string doAncestors(llvm::ArrayRef<llvm::StringRef> modules,33                               llvm::ArrayRef<llvm::StringRef> procs,34                               std::int64_t blockId = 0) {35  std::string prefix;36  const char *tag = "M";37  for (auto mod : modules) {38    prefix.append(tag).append(mod.lower());39    tag = "S";40  }41  for (auto proc : procs)42    prefix.append("F").append(proc.lower());43  if (blockId)44    prefix.append("B").append(std::to_string(blockId));45  return prefix;46}47 48inline llvm::SmallVector<llvm::StringRef>49convertToStringRef(llvm::ArrayRef<std::string> from) {50  return {from.begin(), from.end()};51}52 53inline std::optional<llvm::StringRef>54convertToStringRef(const std::optional<std::string> &from) {55  std::optional<llvm::StringRef> to;56  if (from)57    to = *from;58  return to;59}60 61static std::string readName(llvm::StringRef uniq, std::size_t &i,62                            std::size_t init, std::size_t end) {63  // Allow 'X' to be part of the mangled name, which64  // can happen after the special symbols are replaced65  // in the mangled names by CompilerGeneratedNamesConversionPass.66  for (i = init; i < end && (uniq[i] < 'A' || uniq[i] > 'Z' || uniq[i] == 'X');67       ++i) {68    // do nothing69  }70  return uniq.substr(init, i - init).str();71}72 73static std::int64_t readInt(llvm::StringRef uniq, std::size_t &i,74                            std::size_t init, std::size_t end) {75  for (i = init; i < end && uniq[i] >= '0' && uniq[i] <= '9'; ++i) {76    // do nothing77  }78  std::int64_t result = badValue;79  if (uniq.substr(init, i - init).getAsInteger(10, result))80    return badValue;81  return result;82}83 84std::string fir::NameUniquer::toLower(llvm::StringRef name) {85  return name.lower();86}87 88std::string fir::NameUniquer::intAsString(std::int64_t i) {89  assert(i >= 0);90  return std::to_string(i);91}92 93std::string fir::NameUniquer::doKind(std::int64_t kind) {94  std::string result = "K";95  if (kind < 0)96    return result.append("N").append(intAsString(-kind));97  return result.append(intAsString(kind));98}99 100std::string fir::NameUniquer::doKinds(llvm::ArrayRef<std::int64_t> kinds) {101  std::string result;102  for (auto i : kinds)103    result.append(doKind(i));104  return result;105}106 107std::string fir::NameUniquer::doCommonBlock(llvm::StringRef name) {108  return prefix().append("C").append(toLower(name));109}110 111std::string112fir::NameUniquer::doConstant(llvm::ArrayRef<llvm::StringRef> modules,113                             llvm::ArrayRef<llvm::StringRef> procs,114                             std::int64_t blockId, llvm::StringRef name) {115  return prefix()116      .append(doAncestors(modules, procs, blockId))117      .append("EC")118      .append(toLower(name));119}120 121std::string122fir::NameUniquer::doDispatchTable(llvm::ArrayRef<llvm::StringRef> modules,123                                  llvm::ArrayRef<llvm::StringRef> procs,124                                  std::int64_t blockId, llvm::StringRef name,125                                  llvm::ArrayRef<std::int64_t> kinds) {126  return prefix()127      .append(doAncestors(modules, procs, blockId))128      .append("DT")129      .append(toLower(name))130      .append(doKinds(kinds));131}132 133std::string fir::NameUniquer::doGenerated(llvm::StringRef name) {134  return prefix().append("Q").append(name);135}136 137std::string138fir::NameUniquer::doGenerated(llvm::ArrayRef<llvm::StringRef> modules,139                              llvm::ArrayRef<llvm::StringRef> procs,140                              std::int64_t blockId, llvm::StringRef name) {141  return prefix()142      .append("Q")143      .append(doAncestors(modules, procs, blockId))144      .append(name);145}146 147std::string fir::NameUniquer::doIntrinsicTypeDescriptor(148    llvm::ArrayRef<llvm::StringRef> modules,149    llvm::ArrayRef<llvm::StringRef> procs, std::int64_t blockId,150    IntrinsicType type, std::int64_t kind) {151  const char *name = nullptr;152  switch (type) {153  case IntrinsicType::CHARACTER:154    name = "character";155    break;156  case IntrinsicType::COMPLEX:157    name = "complex";158    break;159  case IntrinsicType::INTEGER:160    name = "integer";161    break;162  case IntrinsicType::LOGICAL:163    name = "logical";164    break;165  case IntrinsicType::REAL:166    name = "real";167    break;168  }169  assert(name && "unknown intrinsic type");170  return prefix()171      .append(doAncestors(modules, procs, blockId))172      .append("YI")173      .append(name)174      .append(doKind(kind));175}176 177std::string178fir::NameUniquer::doProcedure(llvm::ArrayRef<llvm::StringRef> modules,179                              llvm::ArrayRef<llvm::StringRef> procs,180                              llvm::StringRef name) {181  return prefix()182      .append(doAncestors(modules, procs))183      .append("P")184      .append(toLower(name));185}186 187std::string fir::NameUniquer::doType(llvm::ArrayRef<llvm::StringRef> modules,188                                     llvm::ArrayRef<llvm::StringRef> procs,189                                     std::int64_t blockId, llvm::StringRef name,190                                     llvm::ArrayRef<std::int64_t> kinds) {191  return prefix()192      .append(doAncestors(modules, procs, blockId))193      .append("T")194      .append(toLower(name))195      .append(doKinds(kinds));196}197 198std::string199fir::NameUniquer::doTypeDescriptor(llvm::ArrayRef<llvm::StringRef> modules,200                                   llvm::ArrayRef<llvm::StringRef> procs,201                                   std::int64_t blockId, llvm::StringRef name,202                                   llvm::ArrayRef<std::int64_t> kinds) {203  return prefix()204      .append(doAncestors(modules, procs, blockId))205      .append("CT")206      .append(toLower(name))207      .append(doKinds(kinds));208}209 210std::string211fir::NameUniquer::doTypeDescriptor(llvm::ArrayRef<std::string> modules,212                                   llvm::ArrayRef<std::string> procs,213                                   std::int64_t blockId, llvm::StringRef name,214                                   llvm::ArrayRef<std::int64_t> kinds) {215  auto rmodules = convertToStringRef(modules);216  auto rprocs = convertToStringRef(procs);217  return doTypeDescriptor(rmodules, rprocs, blockId, name, kinds);218}219 220std::string221fir::NameUniquer::doVariable(llvm::ArrayRef<llvm::StringRef> modules,222                             llvm::ArrayRef<llvm::StringRef> procs,223                             std::int64_t blockId, llvm::StringRef name) {224  return prefix()225      .append(doAncestors(modules, procs, blockId))226      .append("E")227      .append(toLower(name));228}229 230std::string231fir::NameUniquer::doNamelistGroup(llvm::ArrayRef<llvm::StringRef> modules,232                                  llvm::ArrayRef<llvm::StringRef> procs,233                                  llvm::StringRef name) {234  return prefix()235      .append(doAncestors(modules, procs))236      .append("N")237      .append(toLower(name));238}239 240llvm::StringRef fir::NameUniquer::doProgramEntry() {241  if (mainEntryName.size())242    return mainEntryName;243  return "_QQmain";244}245 246std::pair<fir::NameUniquer::NameKind, fir::NameUniquer::DeconstructedName>247fir::NameUniquer::deconstruct(llvm::StringRef uniq) {248  uniq = fir::NameUniquer::dropTypeConversionMarkers(uniq);249  if (uniq.starts_with("_Q")) {250    llvm::SmallVector<std::string> modules;251    llvm::SmallVector<std::string> procs;252    std::int64_t blockId = 0;253    std::string name;254    llvm::SmallVector<std::int64_t> kinds;255    NameKind nk = NameKind::NOT_UNIQUED;256    for (std::size_t i = 2, end{uniq.size()}; i != end;) {257      switch (uniq[i]) {258      case 'B': // Block259        blockId = readInt(uniq, i, i + 1, end);260        break;261      case 'C': // Common block262        nk = NameKind::COMMON;263        name = readName(uniq, i, i + 1, end);264        break;265      case 'D': // Dispatch table266        nk = NameKind::DISPATCH_TABLE;267        assert(uniq[i + 1] == 'T');268        name = readName(uniq, i, i + 2, end);269        break;270      case 'E':271        if (uniq[i + 1] == 'C') { // Constant Entity272          nk = NameKind::CONSTANT;273          name = readName(uniq, i, i + 2, end);274        } else { // variable Entity275          nk = NameKind::VARIABLE;276          name = readName(uniq, i, i + 1, end);277        }278        break;279      case 'F': // procedure/Function ancestor component of a mangled prefix280        procs.push_back(readName(uniq, i, i + 1, end));281        break;282      case 'K':283        if (uniq[i + 1] == 'N') // Negative Kind284          kinds.push_back(-readInt(uniq, i, i + 2, end));285        else // [positive] Kind286          kinds.push_back(readInt(uniq, i, i + 1, end));287        break;288      case 'M': // Module289      case 'S': // Submodule290        modules.push_back(readName(uniq, i, i + 1, end));291        break;292      case 'N': // Namelist group293        nk = NameKind::NAMELIST_GROUP;294        name = readName(uniq, i, i + 1, end);295        break;296      case 'P': // Procedure/function (itself)297        nk = NameKind::PROCEDURE;298        name = readName(uniq, i, i + 1, end);299        break;300      case 'Q': // UniQue mangle name tag301        nk = NameKind::GENERATED;302        name = uniq;303        i = end;304        break;305      case 'T': // derived Type306        nk = NameKind::DERIVED_TYPE;307        name = readName(uniq, i, i + 1, end);308        break;309      case 'Y':310        if (uniq[i + 1] == 'I') { // tYpe descriptor for an Intrinsic type311          nk = NameKind::INTRINSIC_TYPE_DESC;312          name = readName(uniq, i, i + 1, end);313        } else { // tYpe descriptor314          nk = NameKind::TYPE_DESC;315          name = readName(uniq, i, i + 2, end);316        }317        break;318      default:319        assert(false && "unknown uniquing code");320        break;321      }322    }323    return {nk, DeconstructedName(modules, procs, blockId, name, kinds)};324  }325  return {NameKind::NOT_UNIQUED, DeconstructedName(uniq)};326}327 328bool fir::NameUniquer::isExternalFacingUniquedName(329    const std::pair<fir::NameUniquer::NameKind,330                    fir::NameUniquer::DeconstructedName> &deconstructResult) {331  return (deconstructResult.first == NameKind::PROCEDURE ||332          deconstructResult.first == NameKind::COMMON) &&333         deconstructResult.second.modules.empty() &&334         deconstructResult.second.procs.empty();335}336 337bool fir::NameUniquer::needExternalNameMangling(llvm::StringRef uniquedName) {338  auto result = fir::NameUniquer::deconstruct(uniquedName);339  return result.first != fir::NameUniquer::NameKind::NOT_UNIQUED &&340         fir::NameUniquer::isExternalFacingUniquedName(result);341}342 343bool fir::NameUniquer::belongsToModule(llvm::StringRef uniquedName,344                                       llvm::StringRef moduleName) {345  auto result = fir::NameUniquer::deconstruct(uniquedName);346  return !result.second.modules.empty() &&347         result.second.modules[0] == moduleName;348}349 350static std::string351mangleTypeDescriptorKinds(llvm::ArrayRef<std::int64_t> kinds) {352  if (kinds.empty())353    return "";354  std::string result;355  for (std::int64_t kind : kinds)356    result += (fir::kNameSeparator + std::to_string(kind)).str();357  return result;358}359 360static std::string getDerivedTypeObjectName(llvm::StringRef mangledTypeName,361                                            const llvm::StringRef separator) {362  mangledTypeName =363      fir::NameUniquer::dropTypeConversionMarkers(mangledTypeName);364  auto result = fir::NameUniquer::deconstruct(mangledTypeName);365  if (result.first != fir::NameUniquer::NameKind::DERIVED_TYPE)366    return "";367  std::string varName = separator.str() + result.second.name +368                        mangleTypeDescriptorKinds(result.second.kinds);369  llvm::SmallVector<llvm::StringRef> modules;370  for (const std::string &mod : result.second.modules)371    modules.push_back(mod);372  llvm::SmallVector<llvm::StringRef> procs;373  for (const std::string &proc : result.second.procs)374    procs.push_back(proc);375  return fir::NameUniquer::doVariable(modules, procs, result.second.blockId,376                                      varName);377}378 379std::string380fir::NameUniquer::getTypeDescriptorName(llvm::StringRef mangledTypeName) {381  return getDerivedTypeObjectName(mangledTypeName,382                                  fir::kTypeDescriptorSeparator);383}384 385std::string fir::NameUniquer::getTypeDescriptorAssemblyName(386    llvm::StringRef mangledTypeName) {387  return replaceSpecialSymbols(getTypeDescriptorName(mangledTypeName));388}389 390std::string fir::NameUniquer::getTypeDescriptorBindingTableName(391    llvm::StringRef mangledTypeName) {392  return getDerivedTypeObjectName(mangledTypeName, fir::kBindingTableSeparator);393}394 395std::string396fir::NameUniquer::getComponentInitName(llvm::StringRef mangledTypeName,397                                       llvm::StringRef componentName) {398 399  std::string prefix =400      getDerivedTypeObjectName(mangledTypeName, fir::kComponentInitSeparator);401  return (prefix + fir::kNameSeparator + componentName).str();402}403 404llvm::StringRef405fir::NameUniquer::dropTypeConversionMarkers(llvm::StringRef mangledTypeName) {406  if (mangledTypeName.ends_with(fir::boxprocSuffix))407    return mangledTypeName.drop_back(fir::boxprocSuffix.size());408  return mangledTypeName;409}410 411std::string fir::NameUniquer::replaceSpecialSymbols(const std::string &name) {412  return std::regex_replace(name, std::regex{"\\."}, "X");413}414 415bool fir::NameUniquer::isSpecialSymbol(llvm::StringRef name) {416  return !name.empty() && (name[0] == '.' || name[0] == 'X');417}418