summaryrefslogtreecommitdiffstats
path: root/mlir/lib/TableGen
diff options
context:
space:
mode:
authorLei Zhang <antiagainst@google.com>2020-01-10 11:18:08 -0500
committerLei Zhang <antiagainst@google.com>2020-01-10 18:38:59 -0500
commitca4a55fabbbebef1752fd4e2913c28bb8b510621 (patch)
tree3c3a19de94e1eaba1536ca70c4cf0f9899193779 /mlir/lib/TableGen
parent064087581ab98cca7254b4d0f12ecbed13da2692 (diff)
downloadbcm5719-llvm-ca4a55fabbbebef1752fd4e2913c28bb8b510621.tar.gz
bcm5719-llvm-ca4a55fabbbebef1752fd4e2913c28bb8b510621.zip
[mlir] NFC: put C++ code emission classes in their own files
This exposes thse classes so that they can be used in interfaces. Differential Revision: https://reviews.llvm.org/D72514
Diffstat (limited to 'mlir/lib/TableGen')
-rw-r--r--mlir/lib/TableGen/CMakeLists.txt1
-rw-r--r--mlir/lib/TableGen/OpClass.cpp235
2 files changed, 236 insertions, 0 deletions
diff --git a/mlir/lib/TableGen/CMakeLists.txt b/mlir/lib/TableGen/CMakeLists.txt
index 89e0f024664..08bf24029c4 100644
--- a/mlir/lib/TableGen/CMakeLists.txt
+++ b/mlir/lib/TableGen/CMakeLists.txt
@@ -5,6 +5,7 @@ add_llvm_library(LLVMMLIRTableGen
Dialect.cpp
Format.cpp
Operator.cpp
+ OpClass.cpp
OpInterfaces.cpp
OpTrait.cpp
Pattern.cpp
diff --git a/mlir/lib/TableGen/OpClass.cpp b/mlir/lib/TableGen/OpClass.cpp
new file mode 100644
index 00000000000..1e202df980c
--- /dev/null
+++ b/mlir/lib/TableGen/OpClass.cpp
@@ -0,0 +1,235 @@
+//===- OpClass.cpp - Helper classes for Op C++ code emission --------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/TableGen/OpClass.h"
+
+#include "mlir/TableGen/Format.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace mlir;
+
+//===----------------------------------------------------------------------===//
+// OpMethodSignature definitions
+//===----------------------------------------------------------------------===//
+
+tblgen::OpMethodSignature::OpMethodSignature(StringRef retType, StringRef name,
+ StringRef params)
+ : returnType(retType), methodName(name), parameters(params) {}
+
+void tblgen::OpMethodSignature::writeDeclTo(raw_ostream &os) const {
+ os << returnType << (elideSpaceAfterType(returnType) ? "" : " ") << methodName
+ << "(" << parameters << ")";
+}
+
+void tblgen::OpMethodSignature::writeDefTo(raw_ostream &os,
+ StringRef namePrefix) const {
+ // We need to remove the default values for parameters in method definition.
+ // TODO(antiagainst): We are using '=' and ',' as delimiters for parameter
+ // initializers. This is incorrect for initializer list with more than one
+ // element. Change to a more robust approach.
+ auto removeParamDefaultValue = [](StringRef params) {
+ std::string result;
+ std::pair<StringRef, StringRef> parts;
+ while (!params.empty()) {
+ parts = params.split("=");
+ result.append(result.empty() ? "" : ", ");
+ result.append(parts.first);
+ params = parts.second.split(",").second;
+ }
+ return result;
+ };
+
+ os << returnType << (elideSpaceAfterType(returnType) ? "" : " ") << namePrefix
+ << (namePrefix.empty() ? "" : "::") << methodName << "("
+ << removeParamDefaultValue(parameters) << ")";
+}
+
+bool tblgen::OpMethodSignature::elideSpaceAfterType(StringRef type) {
+ return type.empty() || type.endswith("&") || type.endswith("*");
+}
+
+//===----------------------------------------------------------------------===//
+// OpMethodBody definitions
+//===----------------------------------------------------------------------===//
+
+tblgen::OpMethodBody::OpMethodBody(bool declOnly) : isEffective(!declOnly) {}
+
+tblgen::OpMethodBody &tblgen::OpMethodBody::operator<<(Twine content) {
+ if (isEffective)
+ body.append(content.str());
+ return *this;
+}
+
+tblgen::OpMethodBody &tblgen::OpMethodBody::operator<<(int content) {
+ if (isEffective)
+ body.append(std::to_string(content));
+ return *this;
+}
+
+tblgen::OpMethodBody &
+tblgen::OpMethodBody::operator<<(const FmtObjectBase &content) {
+ if (isEffective)
+ body.append(content.str());
+ return *this;
+}
+
+void tblgen::OpMethodBody::writeTo(raw_ostream &os) const {
+ auto bodyRef = StringRef(body).drop_while([](char c) { return c == '\n'; });
+ os << bodyRef;
+ if (bodyRef.empty() || bodyRef.back() != '\n')
+ os << "\n";
+}
+
+//===----------------------------------------------------------------------===//
+// OpMethod definitions
+//===----------------------------------------------------------------------===//
+
+tblgen::OpMethod::OpMethod(StringRef retType, StringRef name, StringRef params,
+ OpMethod::Property property, bool declOnly)
+ : properties(property), isDeclOnly(declOnly),
+ methodSignature(retType, name, params), methodBody(declOnly) {}
+
+tblgen::OpMethodBody &tblgen::OpMethod::body() { return methodBody; }
+
+bool tblgen::OpMethod::isStatic() const { return properties & MP_Static; }
+
+bool tblgen::OpMethod::isPrivate() const { return properties & MP_Private; }
+
+void tblgen::OpMethod::writeDeclTo(raw_ostream &os) const {
+ os.indent(2);
+ if (isStatic())
+ os << "static ";
+ methodSignature.writeDeclTo(os);
+ os << ";";
+}
+
+void tblgen::OpMethod::writeDefTo(raw_ostream &os, StringRef namePrefix) const {
+ if (isDeclOnly)
+ return;
+
+ methodSignature.writeDefTo(os, namePrefix);
+ os << " {\n";
+ methodBody.writeTo(os);
+ os << "}";
+}
+
+//===----------------------------------------------------------------------===//
+// Class definitions
+//===----------------------------------------------------------------------===//
+
+tblgen::Class::Class(StringRef name) : className(name) {}
+
+tblgen::OpMethod &tblgen::Class::newMethod(StringRef retType, StringRef name,
+ StringRef params,
+ OpMethod::Property property,
+ bool declOnly) {
+ methods.emplace_back(retType, name, params, property, declOnly);
+ return methods.back();
+}
+
+tblgen::OpMethod &tblgen::Class::newConstructor(StringRef params,
+ bool declOnly) {
+ return newMethod("", getClassName(), params, OpMethod::MP_Constructor,
+ declOnly);
+}
+
+void tblgen::Class::newField(StringRef type, StringRef name,
+ StringRef defaultValue) {
+ std::string varName = formatv("{0} {1}", type, name).str();
+ std::string field = defaultValue.empty()
+ ? varName
+ : formatv("{0} = {1}", varName, defaultValue).str();
+ fields.push_back(std::move(field));
+}
+
+void tblgen::Class::writeDeclTo(raw_ostream &os) const {
+ bool hasPrivateMethod = false;
+ os << "class " << className << " {\n";
+ os << "public:\n";
+ for (const auto &method : methods) {
+ if (!method.isPrivate()) {
+ method.writeDeclTo(os);
+ os << '\n';
+ } else {
+ hasPrivateMethod = true;
+ }
+ }
+ os << '\n';
+ os << "private:\n";
+ if (hasPrivateMethod) {
+ for (const auto &method : methods) {
+ if (method.isPrivate()) {
+ method.writeDeclTo(os);
+ os << '\n';
+ }
+ }
+ os << '\n';
+ }
+ for (const auto &field : fields)
+ os.indent(2) << field << ";\n";
+ os << "};\n";
+}
+
+void tblgen::Class::writeDefTo(raw_ostream &os) const {
+ for (const auto &method : methods) {
+ method.writeDefTo(os, className);
+ os << "\n\n";
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// OpClass definitions
+//===----------------------------------------------------------------------===//
+
+tblgen::OpClass::OpClass(StringRef name, StringRef extraClassDeclaration)
+ : Class(name), extraClassDeclaration(extraClassDeclaration),
+ hasOperandAdaptor(true) {}
+
+void tblgen::OpClass::setHasOperandAdaptorClass(bool has) {
+ hasOperandAdaptor = has;
+}
+
+// Adds the given trait to this op.
+void tblgen::OpClass::addTrait(Twine trait) { traits.push_back(trait.str()); }
+
+void tblgen::OpClass::writeDeclTo(raw_ostream &os) const {
+ os << "class " << className << " : public Op<" << className;
+ for (const auto &trait : traits)
+ os << ", " << trait;
+ os << "> {\npublic:\n";
+ os << " using Op::Op;\n";
+ if (hasOperandAdaptor)
+ os << " using OperandAdaptor = " << className << "OperandAdaptor;\n";
+
+ bool hasPrivateMethod = false;
+ for (const auto &method : methods) {
+ if (!method.isPrivate()) {
+ method.writeDeclTo(os);
+ os << "\n";
+ } else {
+ hasPrivateMethod = true;
+ }
+ }
+
+ // TODO: Add line control markers to make errors easier to debug.
+ if (!extraClassDeclaration.empty())
+ os << extraClassDeclaration << "\n";
+
+ if (hasPrivateMethod) {
+ os << "\nprivate:\n";
+ for (const auto &method : methods) {
+ if (method.isPrivate()) {
+ method.writeDeclTo(os);
+ os << "\n";
+ }
+ }
+ }
+
+ os << "};\n";
+}
OpenPOWER on IntegriCloud