brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 09e1bda Raw
112 lines · cpp
1//===========- DirectiveCommonGen.cpp - Directive common info generator -=====//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// OpenMPCommonGen generates utility information from the single OpenMP source10// of truth in llvm/lib/Frontend/OpenMP.11//12//===----------------------------------------------------------------------===//13 14#include "mlir/TableGen/GenInfo.h"15 16#include "llvm/ADT/Twine.h"17#include "llvm/Support/CommandLine.h"18#include "llvm/Support/raw_ostream.h"19#include "llvm/TableGen/DirectiveEmitter.h"20#include "llvm/TableGen/Error.h"21#include "llvm/TableGen/Record.h"22 23using llvm::Clause;24using llvm::EnumVal;25using llvm::raw_ostream;26using llvm::RecordKeeper;27 28// LLVM has multiple places (Clang, Flang, MLIR) where information about29// the directives (OpenMP/OpenACC), and clauses are needed. It is good software30// engineering to keep the common information in a single place to avoid31// duplication, reduce engineering effort and prevent mistakes.32// Currently that common place is llvm/include/llvm/Frontend/OpenMP/OMP.td for33// OpenMP and llvm/include/llvm/Frontend/OpenACC/ACC.td for OpenACC.34// We plan to use this tablegen source to generate all the required35// declarations, functions etc.36//37// Some OpenMP/OpenACC clauses accept only a fixed set of values as inputs.38// These can be represented as a Enum Attributes (EnumAttrDef) in MLIR39// ODS. The emitDecls function below currently generates these enumerations. The40// name of the enumeration is specified in the enumClauseValue field of41// Clause record in OMP.td. This name can be used to specify the type of the42// OpenMP operation's operand. The allowedClauseValues field provides the list43// of ClauseValues which are part of the enumeration.44static bool emitDecls(const RecordKeeper &records, llvm::StringRef dialect,45                      raw_ostream &os) {46  // A dialect must be selected for the generated attributes.47  if (dialect.empty()) {48    llvm::PrintFatalError("a dialect must be selected for the directives via "49                          "'--directives-dialect'");50  }51 52  const auto directiveLanguages =53      records.getAllDerivedDefinitions("DirectiveLanguage");54  assert(!directiveLanguages.empty() && "DirectiveLanguage missing.");55 56  for (const Clause c : records.getAllDerivedDefinitions("Clause")) {57    const auto &clauseVals = c.getClauseVals();58    if (clauseVals.empty())59      continue;60 61    const auto enumName = c.getEnumName();62    assert(!enumName.empty() && "enumClauseValue field not set.");63 64    std::vector<std::string> cvDefs;65    for (const auto &it : llvm::enumerate(clauseVals)) {66      const EnumVal val{it.value()};67      if (!val.isUserVisible())68        continue;69 70      std::string name = val.getFormattedName();71      std::string enumValName(name.length(), ' ');72      llvm::transform(name, enumValName.begin(), llvm::toLower);73      enumValName[0] = llvm::toUpper(enumValName[0]);74      std::string cvDef{(enumName + llvm::Twine(name)).str()};75      os << "def " << cvDef << " : I32EnumAttrCase<\"" << enumValName << "\", "76         << it.index() << ", \"" << name << "\">;\n";77      cvDefs.push_back(cvDef);78    }79 80    os << "def " << enumName << ": I32EnumAttr<\n";81    os << "  \"Clause" << enumName << "\",\n";82    os << "  \"" << enumName << " Clause\",\n";83    os << "  [";84    llvm::interleaveComma(cvDefs, os);85    os << "]> {\n";86    os << "    let cppNamespace = \"::mlir::"87       << directiveLanguages[0]->getValueAsString("cppNamespace") << "\";\n";88    os << "    let genSpecializedAttr = 0;\n";89    os << "}\n";90    llvm::SmallString<16> mnemonic;91    llvm::transform(enumName, std::back_inserter(mnemonic), llvm::toLower);92    os << "def " << enumName << "Attr : EnumAttr<" << dialect << "_Dialect, "93       << enumName << ", \"" << mnemonic << "\">;\n";94  }95  return false;96}97 98static llvm::cl::OptionCategory99    directiveGenCat("Options for gen-directive-decl");100static llvm::cl::opt<std::string>101    dialect("directives-dialect",102            llvm::cl::desc("Generate directives for this dialect"),103            llvm::cl::cat(directiveGenCat), llvm::cl::CommaSeparated);104 105// Registers the generator to mlir-tblgen.106static mlir::GenRegistration genDirectiveDecls(107    "gen-directive-decl",108    "Generate declarations for directives (OpenMP/OpenACC etc.)",109    [](const RecordKeeper &records, raw_ostream &os) {110      return emitDecls(records, dialect, os);111    });112