diff options
| author | Lei Zhang <antiagainst@google.com> | 2020-01-10 11:18:08 -0500 |
|---|---|---|
| committer | Lei Zhang <antiagainst@google.com> | 2020-01-10 18:38:59 -0500 |
| commit | ca4a55fabbbebef1752fd4e2913c28bb8b510621 (patch) | |
| tree | 3c3a19de94e1eaba1536ca70c4cf0f9899193779 /mlir/lib/TableGen | |
| parent | 064087581ab98cca7254b4d0f12ecbed13da2692 (diff) | |
| download | bcm5719-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.txt | 1 | ||||
| -rw-r--r-- | mlir/lib/TableGen/OpClass.cpp | 235 |
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"; +} |

