Files
clang-p2996/mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp
Valentin Clement 0bd9a13691 [mlir][openacc] Use TableGen information for default enum
Use TableGen and information in ACC.td for the Default enum in the OpenACC dialect.
This patch generalize what was done for OpenMP for directives.

Follow up patch after D93576

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D93710
2021-01-12 09:42:42 -05:00

95 lines
3.6 KiB
C++

//===========- DirectiveCommonGen.cpp - Directive common info generator -=====//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// OpenMPCommonGen generates utility information from the single OpenMP source
// of truth in llvm/lib/Frontend/OpenMP.
//
//===----------------------------------------------------------------------===//
#include "mlir/TableGen/GenInfo.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/DirectiveEmitter.h"
#include "llvm/TableGen/Record.h"
using llvm::Clause;
using llvm::ClauseVal;
using llvm::raw_ostream;
using llvm::RecordKeeper;
using llvm::Twine;
// LLVM has multiple places (Clang, Flang, MLIR) where information about
// the directives (OpenMP/OpenACC), and clauses are needed. It is good software
// engineering to keep the common information in a single place to avoid
// duplication, reduce engineering effort and prevent mistakes.
// Currently that common place is llvm/include/llvm/Frontend/OpenMP/OMP.td for
// OpenMP and llvm/include/llvm/Frontend/OpenACC/ACC.td for OpenACC.
// We plan to use this tablegen source to generate all the required
// declarations, functions etc.
//
// Some OpenMP/OpenACC clauses accept only a fixed set of values as inputs.
// These can be represented as a String Enum Attribute (StrEnumAttr) in MLIR
// ODS. The emitDecls function below currently generates these enumerations. The
// name of the enumeration is specified in the enumClauseValue field of
// Clause record in OMP.td. This name can be used to specify the type of the
// OpenMP operation's operand. The allowedClauseValues field provides the list
// of ClauseValues which are part of the enumeration.
static bool emitDecls(const RecordKeeper &recordKeeper, raw_ostream &os) {
const auto &directiveLanguages =
recordKeeper.getAllDerivedDefinitions("DirectiveLanguage");
assert(directiveLanguages.size() != 0 && "DirectiveLanguage missing.");
const auto &clauses = recordKeeper.getAllDerivedDefinitions("Clause");
for (const auto &r : clauses) {
Clause c{r};
const auto &clauseVals = c.getClauseVals();
if (clauseVals.size() <= 0)
continue;
const auto enumName = c.getEnumName();
assert(enumName.size() != 0 && "enumClauseValue field not set.");
std::vector<std::string> cvDefs;
for (const auto &cv : clauseVals) {
ClauseVal cval{cv};
if (!cval.isUserVisible())
continue;
const auto name = cval.getFormattedName();
std::string cvDef{(enumName + llvm::Twine(name)).str()};
os << "def " << cvDef << " : StrEnumAttrCase<\"" << name << "\">;\n";
cvDefs.push_back(cvDef);
}
os << "def " << enumName << ": StrEnumAttr<\n";
os << " \"Clause" << enumName << "\",\n";
os << " \"" << enumName << " Clause\",\n";
os << " [";
for (unsigned int i = 0; i < cvDefs.size(); i++) {
os << cvDefs[i];
if (i != cvDefs.size() - 1)
os << ",";
}
os << "]> {\n";
os << " let cppNamespace = \"::mlir::"
<< directiveLanguages[0]->getValueAsString("cppNamespace") << "\";\n";
os << "}\n";
}
return false;
}
// Registers the generator to mlir-tblgen.
static mlir::GenRegistration genDirectiveDecls(
"gen-directive-decl",
"Generate declarations for directives (OpenMP/OpenACC etc.)",
[](const RecordKeeper &records, raw_ostream &os) {
return emitDecls(records, os);
});