From 74f7aa61c8906df897f482d29d4784c16709b116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 13 Jan 2025 19:10:53 +0100 Subject: [PATCH 01/94] set up mlir-translate for IRDL translation --- mlir/include/mlir/InitAllTranslations.h | 3 + .../include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 34 ++++++++++ .../IRDLToCpp/TranslationRegistration.h | 22 ++++++ mlir/lib/Target/CMakeLists.txt | 1 + mlir/lib/Target/IRDLToCpp/CMakeLists.txt | 9 +++ mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 21 ++++++ .../IRDLToCpp/TranslationRegistration.cpp | 67 +++++++++++++++++++ 7 files changed, 157 insertions(+) create mode 100644 mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h create mode 100644 mlir/include/mlir/Target/IRDLToCpp/TranslationRegistration.h create mode 100644 mlir/lib/Target/IRDLToCpp/CMakeLists.txt create mode 100644 mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp create mode 100644 mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp diff --git a/mlir/include/mlir/InitAllTranslations.h b/mlir/include/mlir/InitAllTranslations.h index 50ad3b285ba41..10e3d440b9751 100644 --- a/mlir/include/mlir/InitAllTranslations.h +++ b/mlir/include/mlir/InitAllTranslations.h @@ -14,6 +14,8 @@ #ifndef MLIR_INITALLTRANSLATIONS_H #define MLIR_INITALLTRANSLATIONS_H +#include "mlir/Target/IRDLToCpp/TranslationRegistration.h" + namespace mlir { void registerFromLLVMIRTranslation(); @@ -29,6 +31,7 @@ inline void registerAllTranslations() { static bool initOnce = []() { registerFromLLVMIRTranslation(); registerFromSPIRVTranslation(); + registerIRDLToCppTranslation(); registerToCppTranslation(); registerToLLVMIRTranslation(); registerToSPIRVTranslation(); diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h new file mode 100644 index 0000000000000..f2760743db887 --- /dev/null +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -0,0 +1,34 @@ +//===- TranslationRegistration.h - Register translation ---------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the registration function for the IRDL to C++ translation. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TARGET_IRDLTOCPP_IRDLTOCPP_H +#define MLIR_TARGET_IRDLTOCPP_IRDLTOCPP_H + +#include "mlir/Dialect/IRDL/IR/IRDL.h" + +namespace mlir { +namespace irdl { + +/// Translates an IRDL dialect definition to a C++ declaration that can be used +/// with MLIR. +LogicalResult translateIRDLDialectToCppDeclHeader(irdl::DialectOp dialect, + raw_ostream &output); + +/// Translates an IRDL dialect definition to a C++ definition that can be used +/// with MLIR. +LogicalResult translateIRDLDialectToCppDef(irdl::DialectOp dialect, + raw_ostream &output); + +} // namespace irdl +} // namespace mlir + +#endif // MLIR_TARGET_IRDLTOCPP_IRDLTOCPP_H diff --git a/mlir/include/mlir/Target/IRDLToCpp/TranslationRegistration.h b/mlir/include/mlir/Target/IRDLToCpp/TranslationRegistration.h new file mode 100644 index 0000000000000..430c519570862 --- /dev/null +++ b/mlir/include/mlir/Target/IRDLToCpp/TranslationRegistration.h @@ -0,0 +1,22 @@ +//===- TranslationRegistration.h - Register translation ---------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the registration function for the IRDL to C++ translation. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TARGET_IRDLTOCPP_TRANSLATIONREGISTRATION_H +#define MLIR_TARGET_IRDLTOCPP_TRANSLATIONREGISTRATION_H + +namespace mlir { + +void registerIRDLToCppTranslation(); + +} // namespace mlir + +#endif // MLIR_TARGET_IRDLTOCPP_TRANSLATIONREGISTRATION_H diff --git a/mlir/lib/Target/CMakeLists.txt b/mlir/lib/Target/CMakeLists.txt index c3ec1b4f1e3fe..281efdc184380 100644 --- a/mlir/lib/Target/CMakeLists.txt +++ b/mlir/lib/Target/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(Cpp) +add_subdirectory(IRDLToCpp) add_subdirectory(SPIRV) add_subdirectory(LLVMIR) add_subdirectory(LLVM) diff --git a/mlir/lib/Target/IRDLToCpp/CMakeLists.txt b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt new file mode 100644 index 0000000000000..b66687fc8b044 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt @@ -0,0 +1,9 @@ +add_mlir_translation_library(MLIRTargetIRDLToCpp + TranslationRegistration.cpp + IRDLToCpp.cpp + + LINK_LIBS PUBLIC + MLIRIR + MLIRIRDL + MLIRTranslateLib + ) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp new file mode 100644 index 0000000000000..280108969a565 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -0,0 +1,21 @@ +//===- IRDLToCpp.cpp - Converts IRDL definitions to C++ -------------------===// +// +// 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/Target/IRDLToCpp/IRDLToCpp.h" + +using namespace mlir; + +LogicalResult irdl::translateIRDLDialectToCppDeclHeader(irdl::DialectOp dialect, + raw_ostream &output) { + return failure(); +} + +LogicalResult irdl::translateIRDLDialectToCppDef(irdl::DialectOp dialect, + raw_ostream &output) { + return failure(); +} diff --git a/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp b/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp new file mode 100644 index 0000000000000..96038ee1f8a97 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp @@ -0,0 +1,67 @@ +//===- TranslationRegistration.cpp - Register translation -----------------===// +// +// 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/Target/IRDLToCpp/TranslationRegistration.h" +#include "mlir/Dialect/IRDL/IR/IRDL.h" +#include "mlir/IR/BuiltinOps.h" +#include "mlir/Target/IRDLToCpp/IRDLToCpp.h" +#include "mlir/Tools/mlir-translate/Translation.h" +#include "llvm/ADT/TypeSwitch.h" +#include "llvm/Support/Casting.h" + +using namespace mlir; + +namespace mlir { + +//===----------------------------------------------------------------------===// +// Translation registration +//===----------------------------------------------------------------------===// + +using IRDLDialectTranslationFunction = + const std::function; + +static LogicalResult +dispatchTranslation(Operation *op, raw_ostream &output, + IRDLDialectTranslationFunction &translation) { + return TypeSwitch(op) + .Case([&](irdl::DialectOp dialectOp) { + return translation(dialectOp, output); + }) + .Case([&](ModuleOp moduleOp) { + for (Operation &op : moduleOp.getBody()->getOperations()) + if (auto dialectOp = llvm::dyn_cast(op)) + if (failed(translation(dialectOp, output))) + return failure(); + return success(); + }) + .Default([](Operation *op) { + return op->emitError( + "unsupported operation for IRDL to C++ translation"); + }); +} + +void registerIRDLToCppTranslation() { + TranslateFromMLIRRegistration regHeader( + "irdl-to-cpp-header", + "translate IRDL dialect definitions to a C++ declaration", + [](Operation *op, raw_ostream &output) { + return dispatchTranslation(op, output, + irdl::translateIRDLDialectToCppDeclHeader); + }, + [](DialectRegistry ®istry) { registry.insert(); }); + + TranslateFromMLIRRegistration reg( + "irdl-to-cpp", "translate IRDL dialect definitions to a C++ definition", + [](Operation *op, raw_ostream &output) { + return dispatchTranslation(op, output, + irdl::translateIRDLDialectToCppDef); + }, + [](DialectRegistry ®istry) { registry.insert(); }); +} + +} // namespace mlir From 9f37bb6e159561e9cdcc9905b280d13b9c032d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 13 Jan 2025 19:22:20 +0100 Subject: [PATCH 02/94] simplify translation registration --- .../include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 11 ++-- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 9 +--- .../IRDLToCpp/TranslationRegistration.cpp | 52 ++++++------------- 3 files changed, 23 insertions(+), 49 deletions(-) diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h index f2760743db887..c9eee3e49c4a6 100644 --- a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -18,15 +18,12 @@ namespace mlir { namespace irdl { -/// Translates an IRDL dialect definition to a C++ declaration that can be used -/// with MLIR. -LogicalResult translateIRDLDialectToCppDeclHeader(irdl::DialectOp dialect, - raw_ostream &output); - /// Translates an IRDL dialect definition to a C++ definition that can be used /// with MLIR. -LogicalResult translateIRDLDialectToCppDef(irdl::DialectOp dialect, - raw_ostream &output); +/// +/// TODO: Document define flags to obtain declaration or definition. +LogicalResult translateIRDLDialectToCpp(irdl::DialectOp dialect, + raw_ostream &output); } // namespace irdl } // namespace mlir diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 280108969a565..646e547bf3983 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -10,12 +10,7 @@ using namespace mlir; -LogicalResult irdl::translateIRDLDialectToCppDeclHeader(irdl::DialectOp dialect, - raw_ostream &output) { - return failure(); -} - -LogicalResult irdl::translateIRDLDialectToCppDef(irdl::DialectOp dialect, - raw_ostream &output) { +LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, + raw_ostream &output) { return failure(); } diff --git a/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp b/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp index 96038ee1f8a97..2a991662738ba 100644 --- a/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp +++ b/mlir/lib/Target/IRDLToCpp/TranslationRegistration.cpp @@ -22,44 +22,26 @@ namespace mlir { // Translation registration //===----------------------------------------------------------------------===// -using IRDLDialectTranslationFunction = - const std::function; - -static LogicalResult -dispatchTranslation(Operation *op, raw_ostream &output, - IRDLDialectTranslationFunction &translation) { - return TypeSwitch(op) - .Case([&](irdl::DialectOp dialectOp) { - return translation(dialectOp, output); - }) - .Case([&](ModuleOp moduleOp) { - for (Operation &op : moduleOp.getBody()->getOperations()) - if (auto dialectOp = llvm::dyn_cast(op)) - if (failed(translation(dialectOp, output))) - return failure(); - return success(); - }) - .Default([](Operation *op) { - return op->emitError( - "unsupported operation for IRDL to C++ translation"); - }); -} - void registerIRDLToCppTranslation() { - TranslateFromMLIRRegistration regHeader( - "irdl-to-cpp-header", - "translate IRDL dialect definitions to a C++ declaration", - [](Operation *op, raw_ostream &output) { - return dispatchTranslation(op, output, - irdl::translateIRDLDialectToCppDeclHeader); - }, - [](DialectRegistry ®istry) { registry.insert(); }); - TranslateFromMLIRRegistration reg( - "irdl-to-cpp", "translate IRDL dialect definitions to a C++ definition", + "irdl-to-cpp", "translate IRDL dialect definitions to C++ definitions", [](Operation *op, raw_ostream &output) { - return dispatchTranslation(op, output, - irdl::translateIRDLDialectToCppDef); + return TypeSwitch(op) + .Case([&](irdl::DialectOp dialectOp) { + return irdl::translateIRDLDialectToCpp(dialectOp, output); + }) + .Case([&](ModuleOp moduleOp) { + for (Operation &op : moduleOp.getBody()->getOperations()) + if (auto dialectOp = llvm::dyn_cast(op)) + if (failed( + irdl::translateIRDLDialectToCpp(dialectOp, output))) + return failure(); + return success(); + }) + .Default([](Operation *op) { + return op->emitError( + "unsupported operation for IRDL to C++ translation"); + }); }, [](DialectRegistry ®istry) { registry.insert(); }); } From c1ca4bd954a6254af7de96624ad21c8f42fc1311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 13 Jan 2025 20:31:07 +0100 Subject: [PATCH 03/94] generate dialect declaration --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 59 ++++++++++++++++++- .../IRDLToCpp/Templates/DialectDecl.txt | 35 +++++++++++ .../lib/Target/IRDLToCpp/Templates/Header.txt | 10 ++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/Header.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 646e547bf3983..b0b62d2e55cf2 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -7,10 +7,67 @@ //===----------------------------------------------------------------------===// #include "mlir/Target/IRDLToCpp/IRDLToCpp.h" +#include "mlir/Support/LLVM.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" using namespace mlir; +constexpr char headerTemplateText[] = +#include "Templates/Header.txt" + ; + +// 0: Namespace open +// 1: Namespace close +// 2: Dialect C++ name +// 3: Dialect name +// 4: Dialect namespace +constexpr char dialectDeclTemplateText[] = +#include "Templates/DialectDecl.txt" + ; + +constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; +constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; + LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { - return failure(); + StringRef dialectName = dialect.getSymName(); + + // TODO: allow more complex path. + llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, + dialectName}; + + std::string namespaceOpen; + std::string namespaceClose; + std::string namespacePathString; + llvm::raw_string_ostream namespaceOpenStream(namespaceOpen); + llvm::raw_string_ostream namespaceCloseStream(namespaceClose); + llvm::raw_string_ostream namespacePathStream(namespacePathString); + for (auto &pathElement : namespaceAbsolutePath) { + namespaceOpenStream << "namespace " << pathElement << " {\n"; + namespaceCloseStream << "} // namespace " << pathElement << "\n"; + namespacePathStream << "::" << pathElement; + } + + // TODO: allow control over C++ name. + std::string cppName; + llvm::raw_string_ostream cppNameStream(cppName); + cppNameStream << llvm::toUpper(dialectName[0]) + << dialectName.slice(1, dialectName.size()) << "Dialect"; + + output << headerTemplateText; + + output << "#ifdef " << declarationMacroFlag << "\n#undef " + << declarationMacroFlag << "\n"; + + output << llvm::formatv(dialectDeclTemplateText, namespaceOpen, + namespaceClose, cppName, dialectName, + namespacePathString); + + output << "#endif\n"; + + return success(); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt new file mode 100644 index 0000000000000..968742f52bcba --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt @@ -0,0 +1,35 @@ +R"( +{0} +class {2} : public ::mlir::Dialect { + explicit {2}(::mlir::MLIRContext *context); + + void initialize(); + friend class ::mlir::MLIRContext; + +public: + ~{2}() override; + static constexpr ::llvm::StringLiteral getDialectNamespace() { + return ::llvm::StringLiteral("{3}"); + } + + /// Parse an attribute registered to this dialect. + ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser, + ::mlir::Type type) const override; + + /// Print an attribute registered to this dialect. + void printAttribute(::mlir::Attribute attr, + ::mlir::DialectAsmPrinter &os) const override; + + /// Parse a type registered to this dialect. + ::mlir::Type parseType(::mlir::DialectAsmParser &parser) const override; + + /// Print a type registered to this dialect. + void printType(::mlir::Type type, + ::mlir::DialectAsmPrinter &os) const override; +}; + +{1} + +MLIR_DECLARE_EXPLICIT_TYPE_ID({4}::{2}) + +)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/Header.txt b/mlir/lib/Target/IRDLToCpp/Templates/Header.txt new file mode 100644 index 0000000000000..c081d6431778a --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/Header.txt @@ -0,0 +1,10 @@ +R"( +/*===- IRDL to C++ Generated file -------------------------------*- C++ -*-===*\ +|* *| +|* Dialect Declarations *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +)" From 483d5a24dfd63763c8dd6e3b8d7b20df47fff36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 13 Jan 2025 20:40:12 +0100 Subject: [PATCH 04/94] add constraints on dialect names --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index b0b62d2e55cf2..ac0b610d3fc10 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -8,6 +8,7 @@ #include "mlir/Target/IRDLToCpp/IRDLToCpp.h" #include "mlir/Support/LLVM.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -36,6 +37,16 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { StringRef dialectName = dialect.getSymName(); + // TODO: deal with no more constraints than the verifier allows. + if (dialectName.size() < 1) + return dialect->emitError("dialect name must be more than one character"); + if (!llvm::isAlpha(dialectName[0])) + return dialect->emitError("dialect name must start with a letter"); + if (!llvm::all_of(dialectName, + [](char c) { return llvm::isAlnum(c) || c == '_'; })) + return dialect->emitError( + "dialect name must only contain letters, numbers or underscores"); + // TODO: allow more complex path. llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; From 71cc646f5be05ebcb6342384261c2a132c55df10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Tue, 14 Jan 2025 00:55:59 +0100 Subject: [PATCH 05/94] add dialect def --- llvm/lib/Support/FormatVariadic.cpp | 1 + mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 75 ++++++++++++++++--- .../IRDLToCpp/Templates/DialectDecl.txt | 6 +- .../Target/IRDLToCpp/Templates/DialectDef.txt | 12 +++ 4 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt diff --git a/llvm/lib/Support/FormatVariadic.cpp b/llvm/lib/Support/FormatVariadic.cpp index f3e8d0a7fe6f3..8eb30b8338f90 100644 --- a/llvm/lib/Support/FormatVariadic.cpp +++ b/llvm/lib/Support/FormatVariadic.cpp @@ -82,6 +82,7 @@ static std::optional parseReplacementItem(StringRef Spec) { } RepString = RepString.trim(); if (!RepString.empty()) { + llvm::errs() << "content is: " << RepString << "\n"; assert(0 && "Unexpected characters found in replacement string!"); return std::nullopt; } diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index ac0b610d3fc10..61be2dc1cf385 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -24,15 +24,68 @@ constexpr char headerTemplateText[] = // 0: Namespace open // 1: Namespace close // 2: Dialect C++ name -// 3: Dialect name -// 4: Dialect namespace +// 3: Dialect namespace +// 4: Dialect name constexpr char dialectDeclTemplateText[] = #include "Templates/DialectDecl.txt" ; +// 0: Namespace open +// 1: Namespace close +// 2: Dialect C++ name +// 3: Dialect namespace +constexpr char dialectDefTemplateText[] = +#include "Templates/DialectDef.txt" + ; + constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; +namespace { + +struct UsefulStrings { + StringRef dialectName; + StringRef dialectCppName; + + StringRef namespaceOpen; + StringRef namespaceClose; + StringRef namespacePathString; +}; + +} // namespace + +static LogicalResult generateInclude(irdl::DialectOp dialect, + raw_ostream &output, + UsefulStrings &usefulStrings) { + output << "#ifdef " << declarationMacroFlag << "\n#undef " + << declarationMacroFlag << "\n"; + + output << llvm::formatv( + dialectDeclTemplateText, usefulStrings.namespaceOpen, + usefulStrings.namespaceClose, usefulStrings.dialectCppName, + usefulStrings.namespacePathString, usefulStrings.dialectName); + + output << "#endif // " << declarationMacroFlag << "\n"; + + return success(); +} + +static LogicalResult generateLib(irdl::DialectOp dialect, + raw_ostream &output, + UsefulStrings &usefulStrings) { + output << "#ifdef " << definitionMacroFlag << "\n#undef " + << definitionMacroFlag << "\n"; + + output << llvm::formatv( + dialectDefTemplateText, usefulStrings.namespaceOpen, + usefulStrings.namespaceClose, usefulStrings.dialectCppName, + usefulStrings.namespacePathString); + + output << "#endif // " << definitionMacroFlag << "\n"; + + return success(); +} + LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { StringRef dialectName = dialect.getSymName(); @@ -69,16 +122,20 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, cppNameStream << llvm::toUpper(dialectName[0]) << dialectName.slice(1, dialectName.size()) << "Dialect"; - output << headerTemplateText; + UsefulStrings usefulStrings; + usefulStrings.dialectName = dialectName; + usefulStrings.dialectCppName = cppName; + usefulStrings.namespaceOpen = namespaceOpen; + usefulStrings.namespaceClose = namespaceClose; + usefulStrings.namespacePathString = namespacePathString; - output << "#ifdef " << declarationMacroFlag << "\n#undef " - << declarationMacroFlag << "\n"; + output << headerTemplateText; - output << llvm::formatv(dialectDeclTemplateText, namespaceOpen, - namespaceClose, cppName, dialectName, - namespacePathString); + if (failed(generateInclude(dialect, output, usefulStrings))) + return failure(); - output << "#endif\n"; + if (failed(generateLib(dialect, output, usefulStrings))) + return failure(); return success(); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt index 968742f52bcba..763a738ddb680 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt @@ -9,7 +9,7 @@ class {2} : public ::mlir::Dialect { public: ~{2}() override; static constexpr ::llvm::StringLiteral getDialectNamespace() { - return ::llvm::StringLiteral("{3}"); + return ::llvm::StringLiteral("{4}"); } /// Parse an attribute registered to this dialect. @@ -30,6 +30,6 @@ public: {1} -MLIR_DECLARE_EXPLICIT_TYPE_ID({4}::{2}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({3}::{2}) -)" \ No newline at end of file +)" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt new file mode 100644 index 0000000000000..ce8724e0c39a0 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt @@ -0,0 +1,12 @@ +R"( +MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) +{0} +{2}::{2}(::mlir::MLIRContext *context) + : ::mlir::Dialect(getDialectNamespace(), context, ::mlir::TypeID::get<{2}>()) +{{ + initialize(); +} + +{2}::~{2}() = default; +{1} +)" From 4b6bd5dc1738c05b4d55b92ee277359338f42bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Tue, 14 Jan 2025 18:55:07 +0100 Subject: [PATCH 06/94] first draft of op template --- .../IRDLToCpp/Templates/OperationDecl.txt | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt new file mode 100644 index 0000000000000..ad9de6b7f981b --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -0,0 +1,137 @@ +0: Name +1: CppName +2: DialectName + +3: open namespace +4: close namespace + +R"( +{3} + +namespace detail { +class {1}GenericAdaptorBase { +public: +protected: + ::mlir::DictionaryAttr odsAttrs; + ::std::optional<::mlir::OperationName> odsOpName; + ::mlir::RegionRange odsRegions; +public: + {1}GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) + odsOpName.emplace("{2}.{0}", odsAttrs.getContext()); + } + + {1}GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} + + std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); + ::mlir::DictionaryAttr getAttributes() { + return odsAttrs; + } + +}; +} // namespace detail + +template +class {1}GenericAdaptor : public detail::{1}GenericAdaptorBase { + using ValueT = ::llvm::detail::ValueOfRange; + using Base = detail::{1}GenericAdaptorBase; +public: + {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} + + {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {}) : {1}GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{}), regions) {} + + {1}GenericAdaptor(RangeT values, const {1}GenericAdaptorBase &base) : Base(base), odsOperands(values) {} + + template >> + {1}GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} + + std::pair getODSOperandIndexAndLength(unsigned index) { + return Base::getODSOperandIndexAndLength(index, odsOperands.size()); + } + + RangeT getODSOperands(unsigned index) { + auto valueRange = getODSOperandIndexAndLength(index); + return {std::next(odsOperands.begin(), valueRange.first), + std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; + } + + RangeT getArgs() { + return getODSOperands(0); + } + + RangeT getOperands() { + return odsOperands; + } + +private: + RangeT odsOperands; +}; + +class {1}Adaptor : public {1}GenericAdaptor<::mlir::ValueRange> { +public: + using {1}GenericAdaptor::{1}GenericAdaptor; + {1}Adaptor({1} op); + + ::llvm::LogicalResult verify(::mlir::Location loc); +}; + +class {1} : public ::mlir::Op<{1}> { +public: + using Op::Op; + using Op::print; + using Adaptor = {1}Adaptor; + template + using GenericAdaptor = {1}GenericAdaptor; + using FoldAdaptor = GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute>>; + static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { + return {}; + } + + static constexpr ::llvm::StringLiteral getOperationName() { + return ::llvm::StringLiteral("{2}.{0}"); + } + + std::pair getODSOperandIndexAndLength(unsigned index); + ::mlir::Operation::operand_range getODSOperands(unsigned index) { + auto valueRange = getODSOperandIndexAndLength(index); + return {std::next(getOperation()->operand_begin(), valueRange.first), + std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; + } + + ::mlir::Operation::operand_range getArgs() { + return getODSOperands(0); + } + + ::mlir::MutableOperandRange getArgsMutable(); + std::pair getODSResultIndexAndLength(unsigned index) { + return {index, 1}; + } + + ::mlir::Operation::result_range getODSResults(unsigned index) { + auto valueRange = getODSResultIndexAndLength(index); + return {std::next(getOperation()->result_begin(), valueRange.first), + std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; + } + + ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() { + return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); + } + + static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type output, ::mlir::ValueRange args); + static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + ::llvm::LogicalResult verifyInvariantsImpl(); + ::llvm::LogicalResult verifyInvariants(); + std::unique_ptr<::mlir::irdl::Constraint> getVerifier(::mlir::ArrayRef valueToConstr, ::mlir::DenseMap<::mlir::irdl::TypeOp, + std::unique_ptr<::mlir::DynamicTypeDefinition>> const&types, ::mlir::DenseMap<::mlir::irdl::AttributeOp, + std::unique_ptr<::mlir::DynamicAttrDefinition>> const&attrs); + static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); + void print(::mlir::OpAsmPrinter &_odsPrinter); +public: +}; + + +{4} + +MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{1}) + +)" \ No newline at end of file From 39dda7dfea2d95c8601d8db8beb64b6eaef587a0 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Wed, 15 Jan 2025 15:20:36 +0000 Subject: [PATCH 07/94] added base type class --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 26 ++++++++++++++++--- .../Target/IRDLToCpp/Templates/TypeDecl.txt | 18 +++++++++++++ .../IRDLToCpp/Templates/TypeHeaderDecl.txt | 12 +++++++++ .../IRDLToCpp/Templates/TypeHeaderDef.txt | 10 +++++++ 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 61be2dc1cf385..9026c8ed12c47 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -38,14 +38,24 @@ constexpr char dialectDefTemplateText[] = #include "Templates/DialectDef.txt" ; + constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; +constexpr char typeHeaderDeclTemplateText[] = +#include "Templates/TypeHeaderDecl.txt" + ; + +constexpr char typeHeaderDefTemplateText[] = +#include "Templates/TypeHeaderDef.txt" + ; + namespace { struct UsefulStrings { StringRef dialectName; StringRef dialectCppName; + StringRef dialectCppShortName; StringRef namespaceOpen; StringRef namespaceClose; @@ -65,6 +75,10 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, usefulStrings.namespaceClose, usefulStrings.dialectCppName, usefulStrings.namespacePathString, usefulStrings.dialectName); + output << llvm::formatv( + typeHeaderDeclTemplateText, usefulStrings.dialectCppShortName + ); + output << "#endif // " << declarationMacroFlag << "\n"; return success(); @@ -81,6 +95,10 @@ static LogicalResult generateLib(irdl::DialectOp dialect, usefulStrings.namespaceClose, usefulStrings.dialectCppName, usefulStrings.namespacePathString); + output << llvm::formatv( + typeHeaderDefTemplateText, usefulStrings.dialectCppShortName, usefulStrings.dialectCppName + ); + output << "#endif // " << definitionMacroFlag << "\n"; return success(); @@ -117,14 +135,13 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, } // TODO: allow control over C++ name. - std::string cppName; - llvm::raw_string_ostream cppNameStream(cppName); - cppNameStream << llvm::toUpper(dialectName[0]) - << dialectName.slice(1, dialectName.size()) << "Dialect"; + std::string cppShortName = llvm::formatv("{0}{1}", llvm::toUpper(dialectName[0]), dialectName.slice(1, dialectName.size())); + std::string cppName = llvm::formatv("{0}Dialect", cppShortName); UsefulStrings usefulStrings; usefulStrings.dialectName = dialectName; usefulStrings.dialectCppName = cppName; + usefulStrings.dialectCppShortName = cppShortName; usefulStrings.namespaceOpen = namespaceOpen; usefulStrings.namespaceClose = namespaceClose; usefulStrings.namespacePathString = namespacePathString; @@ -139,3 +156,4 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, return success(); } + diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt new file mode 100644 index 0000000000000..2fcd65f168a07 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -0,0 +1,18 @@ +/* +{0}: Dialect Name +{1}: Dialect CppName +{2}: Type Name +{3}: Type CppName +*/ + +R"( +class {3}Type : public ::mlir::Type::TypeBase<{3}Type, {1}Type, ::mlir::TypeStorage> { +public: + using Base::Base; + static constexpr ::llvm::StringLiteral name = "{0}.{2}"; + static constexpr ::llvm::StringLiteral dialectName = "{0}"; + static constexpr ::llvm::StringLiteral getMnemonic() { + return {"{2}"}; + } +}; +)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt new file mode 100644 index 0000000000000..4c62fc00912ca --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -0,0 +1,12 @@ +/* +{0}: Dialect CppShortName +*/ + +R"( +class {0}Type : public ::mlir::Type {{ +public: + using Type::Type; + + static bool classof(Type type); +}; +)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt new file mode 100644 index 0000000000000..998afc87f37b0 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt @@ -0,0 +1,10 @@ +/* +{0}: Dialect CppShortName +{1}: Dialect CppName +*/ + +R"( +bool {0}Type::classof(Type type) {{ + return llvm::isa<{1}>(type.getDialect()); +} +)" From cb7337ddb87bbe05c83f95fc2ce0ea1f68be3b51 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Thu, 16 Jan 2025 14:05:33 +0000 Subject: [PATCH 08/94] generate singleton types --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 87 ++++++++++++++----- .../Target/IRDLToCpp/Templates/TypeDecl.txt | 4 +- .../IRDLToCpp/Templates/TypeHeaderDecl.txt | 4 +- .../IRDLToCpp/Templates/TypeHeaderDef.txt | 4 +- .../Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 12 +++ 5 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 9026c8ed12c47..5a2a7e66c402a 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -38,17 +38,20 @@ constexpr char dialectDefTemplateText[] = #include "Templates/DialectDef.txt" ; - constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; constexpr char typeHeaderDeclTemplateText[] = #include "Templates/TypeHeaderDecl.txt" - ; + ; constexpr char typeHeaderDefTemplateText[] = #include "Templates/TypeHeaderDef.txt" - ; + ; + +constexpr char typeDeclTemplateText[] = +#include "Templates/TypeDecl.txt" + ; namespace { @@ -56,17 +59,47 @@ struct UsefulStrings { StringRef dialectName; StringRef dialectCppName; StringRef dialectCppShortName; + StringRef dialectBaseTypeName; StringRef namespaceOpen; StringRef namespaceClose; StringRef namespacePathString; }; +struct TypeStrings { + StringRef typeName; + StringRef typeCppName; + StringRef typeCppShortName; +}; + +static std::string capitalize(StringRef str) { + return llvm::formatv("{0}{1}", llvm::toUpper(str[0]), + str.slice(1, str.size())); +} + } // namespace +static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, + UsefulStrings &usefulStrings) { + + std::string typeCppShortName = capitalize(type.getSymName()); + std::string typeCppName = llvm::formatv("{0}Type", typeCppShortName); + + TypeStrings typeStrings; + typeStrings.typeName = type.getSymName(); + typeStrings.typeCppShortName = typeCppShortName; + typeStrings.typeCppName = typeCppName; + + output << llvm::formatv(typeDeclTemplateText, usefulStrings.dialectName, + usefulStrings.dialectBaseTypeName, + typeStrings.typeName, typeStrings.typeCppName); + + return success(); +} + static LogicalResult generateInclude(irdl::DialectOp dialect, - raw_ostream &output, - UsefulStrings &usefulStrings) { + raw_ostream &output, + UsefulStrings &usefulStrings) { output << "#ifdef " << declarationMacroFlag << "\n#undef " << declarationMacroFlag << "\n"; @@ -75,29 +108,39 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, usefulStrings.namespaceClose, usefulStrings.dialectCppName, usefulStrings.namespacePathString, usefulStrings.dialectName); - output << llvm::formatv( - typeHeaderDeclTemplateText, usefulStrings.dialectCppShortName - ); + output << usefulStrings.namespaceOpen; + output << llvm::formatv(typeHeaderDeclTemplateText, + usefulStrings.dialectBaseTypeName); + + auto &®ion = dialect->getRegion(0); + auto &&block = region.getBlocks().front(); + for (auto &&op : block) { + if (auto typeop = llvm::dyn_cast_or_null(op)) + generateTypeInclude(typeop, output, usefulStrings); + } + + output << usefulStrings.namespaceClose; output << "#endif // " << declarationMacroFlag << "\n"; return success(); } -static LogicalResult generateLib(irdl::DialectOp dialect, - raw_ostream &output, - UsefulStrings &usefulStrings) { +static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, + UsefulStrings &usefulStrings) { output << "#ifdef " << definitionMacroFlag << "\n#undef " << definitionMacroFlag << "\n"; - output << llvm::formatv( - dialectDefTemplateText, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose, usefulStrings.dialectCppName, - usefulStrings.namespacePathString); + output << llvm::formatv(dialectDefTemplateText, usefulStrings.namespaceOpen, + usefulStrings.namespaceClose, + usefulStrings.dialectCppName, + usefulStrings.namespacePathString); - output << llvm::formatv( - typeHeaderDefTemplateText, usefulStrings.dialectCppShortName, usefulStrings.dialectCppName - ); + output << usefulStrings.namespaceOpen; + output << llvm::formatv(typeHeaderDefTemplateText, + usefulStrings.dialectBaseTypeName, + usefulStrings.dialectCppName); + output << usefulStrings.namespaceClose; output << "#endif // " << definitionMacroFlag << "\n"; @@ -121,7 +164,6 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, // TODO: allow more complex path. llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; - std::string namespaceOpen; std::string namespaceClose; std::string namespacePathString; @@ -135,11 +177,15 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, } // TODO: allow control over C++ name. - std::string cppShortName = llvm::formatv("{0}{1}", llvm::toUpper(dialectName[0]), dialectName.slice(1, dialectName.size())); + std::string cppShortName = + llvm::formatv("{0}{1}", llvm::toUpper(dialectName[0]), + dialectName.slice(1, dialectName.size())); + std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); UsefulStrings usefulStrings; usefulStrings.dialectName = dialectName; + usefulStrings.dialectBaseTypeName = dialectBaseTypeName; usefulStrings.dialectCppName = cppName; usefulStrings.dialectCppShortName = cppShortName; usefulStrings.namespaceOpen = namespaceOpen; @@ -156,4 +202,3 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, return success(); } - diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index 2fcd65f168a07..0764792bdde1d 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -1,12 +1,12 @@ /* {0}: Dialect Name -{1}: Dialect CppName +{1}: Dialect BaseTypeName {2}: Type Name {3}: Type CppName */ R"( -class {3}Type : public ::mlir::Type::TypeBase<{3}Type, {1}Type, ::mlir::TypeStorage> { +class {3} : public ::mlir::Type::TypeBase<{3}, {1}, ::mlir::TypeStorage> { public: using Base::Base; static constexpr ::llvm::StringLiteral name = "{0}.{2}"; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index 4c62fc00912ca..51f4ed5266d5e 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -1,9 +1,9 @@ /* -{0}: Dialect CppShortName +{0}: Dialect BaseTypeName */ R"( -class {0}Type : public ::mlir::Type {{ +class {0} : public ::mlir::Type {{ public: using Type::Type; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt index 998afc87f37b0..da1d204c4c68a 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt @@ -1,10 +1,10 @@ /* -{0}: Dialect CppShortName +{0}: Dialect BaseTypeName {1}: Dialect CppName */ R"( -bool {0}Type::classof(Type type) {{ +bool {0}::classof(Type type) {{ return llvm::isa<{1}>(type.getDialect()); } )" diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir new file mode 100644 index 0000000000000..27820a873f72c --- /dev/null +++ b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir @@ -0,0 +1,12 @@ +// RUN: mlir-opt %s | mlir-opt | FileCheck %s + +module { + irdl.dialect @testd { + irdl.type @singleton + + irdl.operation @any { + %0 = irdl.any + irdl.results(%0) + } + } +} From 451c4395c1eb352b053e6786208acef0d1e4cf03 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 17 Jan 2025 11:38:04 +0000 Subject: [PATCH 09/94] basic operation work + escaped braces in operationdecl --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 43 +++++++++++-------- .../IRDLToCpp/Templates/OperationDecl.txt | 28 ++++++------ .../Target/IRDLToCpp/Templates/TypeDecl.txt | 24 +++++++---- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 5a2a7e66c402a..4f281d2b7c596 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -53,6 +53,10 @@ constexpr char typeDeclTemplateText[] = #include "Templates/TypeDecl.txt" ; +constexpr char opDeclTemplateText[] = +#include "Templates/OperationDecl.txt" + ; + namespace { struct UsefulStrings { @@ -66,12 +70,6 @@ struct UsefulStrings { StringRef namespacePathString; }; -struct TypeStrings { - StringRef typeName; - StringRef typeCppName; - StringRef typeCppShortName; -}; - static std::string capitalize(StringRef str) { return llvm::formatv("{0}{1}", llvm::toUpper(str[0]), str.slice(1, str.size())); @@ -82,17 +80,29 @@ static std::string capitalize(StringRef str) { static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, UsefulStrings &usefulStrings) { - std::string typeCppShortName = capitalize(type.getSymName()); + StringRef typeName = type.getSymName(); + std::string typeCppShortName = capitalize(typeName); std::string typeCppName = llvm::formatv("{0}Type", typeCppShortName); - TypeStrings typeStrings; - typeStrings.typeName = type.getSymName(); - typeStrings.typeCppShortName = typeCppShortName; - typeStrings.typeCppName = typeCppName; + output << llvm::formatv( + typeDeclTemplateText, typeName, typeCppName, usefulStrings.dialectName, + usefulStrings.dialectBaseTypeName, usefulStrings.namespaceOpen, + usefulStrings.namespaceClose); - output << llvm::formatv(typeDeclTemplateText, usefulStrings.dialectName, - usefulStrings.dialectBaseTypeName, - typeStrings.typeName, typeStrings.typeCppName); + return success(); +} + +static LogicalResult generateOperationInclude(irdl::OperationOp op, + raw_ostream &output, + UsefulStrings &usefulStrings) { + + StringRef opName = op.getSymName(); + std::string opCppShortName = capitalize(opName); + std::string opCppName = llvm::formatv("{0}Op", opCppShortName); + + output << llvm::formatv( + opDeclTemplateText, opName, opCppName, usefulStrings.dialectName, + usefulStrings.namespaceOpen, usefulStrings.namespaceClose); return success(); } @@ -108,7 +118,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, usefulStrings.namespaceClose, usefulStrings.dialectCppName, usefulStrings.namespacePathString, usefulStrings.dialectName); - output << usefulStrings.namespaceOpen; output << llvm::formatv(typeHeaderDeclTemplateText, usefulStrings.dialectBaseTypeName); @@ -117,10 +126,10 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, for (auto &&op : block) { if (auto typeop = llvm::dyn_cast_or_null(op)) generateTypeInclude(typeop, output, usefulStrings); + if (auto operationOp = llvm::dyn_cast_or_null(op)) + generateOperationInclude(operationOp, output, usefulStrings); } - output << usefulStrings.namespaceClose; - output << "#endif // " << declarationMacroFlag << "\n"; return success(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt index ad9de6b7f981b..3335e97acc7da 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -1,9 +1,11 @@ -0: Name -1: CppName -2: DialectName +/* +0: Operation Name +1: Operation CppName +2: Dialect Name 3: open namespace 4: close namespace +*/ R"( {3} @@ -23,7 +25,7 @@ public: {1}GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); - ::mlir::DictionaryAttr getAttributes() { + ::mlir::DictionaryAttr getAttributes() {{ return odsAttrs; } @@ -44,21 +46,21 @@ public: template >> {1}GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} - std::pair getODSOperandIndexAndLength(unsigned index) { + std::pair getODSOperandIndexAndLength(unsigned index) {{ return Base::getODSOperandIndexAndLength(index, odsOperands.size()); } RangeT getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); - return {std::next(odsOperands.begin(), valueRange.first), + return {{std::next(odsOperands.begin(), valueRange.first), std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } - RangeT getArgs() { + RangeT getArgs() {{ return getODSOperands(0); } - RangeT getOperands() { + RangeT getOperands() {{ return odsOperands; } @@ -93,26 +95,26 @@ public: std::pair getODSOperandIndexAndLength(unsigned index); ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); - return {std::next(getOperation()->operand_begin(), valueRange.first), + return {{std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } - ::mlir::Operation::operand_range getArgs() { + ::mlir::Operation::operand_range getArgs() {{ return getODSOperands(0); } ::mlir::MutableOperandRange getArgsMutable(); std::pair getODSResultIndexAndLength(unsigned index) { - return {index, 1}; + return {{index, 1}; } ::mlir::Operation::result_range getODSResults(unsigned index) { auto valueRange = getODSResultIndexAndLength(index); - return {std::next(getOperation()->result_begin(), valueRange.first), + return {{std::next(getOperation()->result_begin(), valueRange.first), std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } - ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() { + ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() {{ return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index 0764792bdde1d..3ad6edac09221 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -1,18 +1,26 @@ /* -{0}: Dialect Name -{1}: Dialect BaseTypeName -{2}: Type Name -{3}: Type CppName +{0}: Type Name +{1}: Type CppName +{2}: Dialect Name +{3}: Dialect BaseTypeName + +{4}: Namespace open +{5}: Namespace close */ R"( -class {3} : public ::mlir::Type::TypeBase<{3}, {1}, ::mlir::TypeStorage> { + +{4} + +class {1} : public ::mlir::Type::TypeBase<{1}, {3}, ::mlir::TypeStorage> { public: using Base::Base; - static constexpr ::llvm::StringLiteral name = "{0}.{2}"; - static constexpr ::llvm::StringLiteral dialectName = "{0}"; + static constexpr ::llvm::StringLiteral name = "{2}.{0}"; + static constexpr ::llvm::StringLiteral dialectName = "{2}"; static constexpr ::llvm::StringLiteral getMnemonic() { - return {"{2}"}; + return {"{0}"}; } }; + +{5} )" \ No newline at end of file From f25ce38dfc91ae4b446a5b078980d7c299579023 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 17 Jan 2025 12:48:44 +0000 Subject: [PATCH 10/94] mlir explicit type id --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 5 +++-- mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt | 2 ++ mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt | 10 ++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 4f281d2b7c596..03aa4e1626e99 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -118,8 +118,9 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, usefulStrings.namespaceClose, usefulStrings.dialectCppName, usefulStrings.namespacePathString, usefulStrings.dialectName); - output << llvm::formatv(typeHeaderDeclTemplateText, - usefulStrings.dialectBaseTypeName); + output << llvm::formatv( + typeHeaderDeclTemplateText, usefulStrings.dialectBaseTypeName, + usefulStrings.namespaceOpen, usefulStrings.namespaceClose); auto &®ion = dialect->getRegion(0); auto &&block = region.getBlocks().front(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index 3ad6edac09221..a000c870f4e75 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -23,4 +23,6 @@ public: }; {5} + +MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{1}) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index 51f4ed5266d5e..6e7ffceba1755 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -1,12 +1,22 @@ /* {0}: Dialect BaseTypeName + +{1}: Open namespace +{2}: Close namespace */ + R"( +{1} + class {0} : public ::mlir::Type {{ public: using Type::Type; static bool classof(Type type); }; + +{2} + +MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{0}) )" \ No newline at end of file From 228729ddcabac70b6a5069c10e6f11d60edeaff7 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 17 Jan 2025 15:29:22 +0000 Subject: [PATCH 11/94] used namespace path for type reg --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 52 ++++++++++++++----- .../IRDLToCpp/Templates/OperationDecl.txt | 37 +++++++------ .../Target/IRDLToCpp/Templates/TypeDecl.txt | 3 +- .../IRDLToCpp/Templates/TypeHeaderDecl.txt | 3 +- 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 03aa4e1626e99..a1df613f913cf 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -67,7 +67,7 @@ struct UsefulStrings { StringRef namespaceOpen; StringRef namespaceClose; - StringRef namespacePathString; + StringRef namespacePath; }; static std::string capitalize(StringRef str) { @@ -87,7 +87,7 @@ static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, output << llvm::formatv( typeDeclTemplateText, typeName, typeCppName, usefulStrings.dialectName, usefulStrings.dialectBaseTypeName, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose); + usefulStrings.namespaceClose, usefulStrings.namespacePath); return success(); } @@ -100,9 +100,30 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, std::string opCppShortName = capitalize(opName); std::string opCppName = llvm::formatv("{0}Op", opCppShortName); + auto &&block = op.getBody().getBlocks().front(); + + const unsigned operandCount = ([&block]() -> unsigned { + auto operands = block.getOps(); + if (operands.empty()) + return 0; + + // at most 1, guaranteed by verifiers + auto &&operand = *operands.begin(); + return operand.getNumOperands(); + })(); + + const unsigned resultCount = ([&block]() -> unsigned { + auto resultsOps = block.getOps(); + + // exactly 1 resultOp, guaranteed by verifiers + auto &&resultsOp = *resultsOps.begin(); + return resultsOp.getNumOperands(); + })(); + output << llvm::formatv( opDeclTemplateText, opName, opCppName, usefulStrings.dialectName, - usefulStrings.namespaceOpen, usefulStrings.namespaceClose); + operandCount, resultCount, usefulStrings.namespaceOpen, + usefulStrings.namespaceClose, usefulStrings.namespacePath); return success(); } @@ -116,19 +137,24 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, output << llvm::formatv( dialectDeclTemplateText, usefulStrings.namespaceOpen, usefulStrings.namespaceClose, usefulStrings.dialectCppName, - usefulStrings.namespacePathString, usefulStrings.dialectName); + usefulStrings.namespacePath, usefulStrings.dialectName); output << llvm::formatv( typeHeaderDeclTemplateText, usefulStrings.dialectBaseTypeName, - usefulStrings.namespaceOpen, usefulStrings.namespaceClose); + usefulStrings.namespaceOpen, usefulStrings.namespaceClose, + usefulStrings.namespacePath); auto &®ion = dialect->getRegion(0); auto &&block = region.getBlocks().front(); for (auto &&op : block) { - if (auto typeop = llvm::dyn_cast_or_null(op)) - generateTypeInclude(typeop, output, usefulStrings); - if (auto operationOp = llvm::dyn_cast_or_null(op)) - generateOperationInclude(operationOp, output, usefulStrings); + if (auto typeop = llvm::dyn_cast_or_null(op)) { + if (failed(generateTypeInclude(typeop, output, usefulStrings))) + return failure(); + } + if (auto operationOp = llvm::dyn_cast_or_null(op)) { + if (failed(generateOperationInclude(operationOp, output, usefulStrings))) + return failure(); + } } output << "#endif // " << declarationMacroFlag << "\n"; @@ -144,7 +170,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, output << llvm::formatv(dialectDefTemplateText, usefulStrings.namespaceOpen, usefulStrings.namespaceClose, usefulStrings.dialectCppName, - usefulStrings.namespacePathString); + usefulStrings.namespacePath); output << usefulStrings.namespaceOpen; output << llvm::formatv(typeHeaderDefTemplateText, @@ -176,10 +202,10 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, dialectName}; std::string namespaceOpen; std::string namespaceClose; - std::string namespacePathString; + std::string namespacePath; llvm::raw_string_ostream namespaceOpenStream(namespaceOpen); llvm::raw_string_ostream namespaceCloseStream(namespaceClose); - llvm::raw_string_ostream namespacePathStream(namespacePathString); + llvm::raw_string_ostream namespacePathStream(namespacePath); for (auto &pathElement : namespaceAbsolutePath) { namespaceOpenStream << "namespace " << pathElement << " {\n"; namespaceCloseStream << "} // namespace " << pathElement << "\n"; @@ -200,7 +226,7 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, usefulStrings.dialectCppShortName = cppShortName; usefulStrings.namespaceOpen = namespaceOpen; usefulStrings.namespaceClose = namespaceClose; - usefulStrings.namespacePathString = namespacePathString; + usefulStrings.namespacePath = namespacePath; output << headerTemplateText; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt index 3335e97acc7da..467c7bb8e9fe0 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -2,13 +2,16 @@ 0: Operation Name 1: Operation CppName 2: Dialect Name +3: Operand count +4: Result count -3: open namespace -4: close namespace +5: open namespace +6: close namespace +7: namespace path */ R"( -{3} +{5} namespace detail { class {1}GenericAdaptorBase { @@ -18,11 +21,11 @@ protected: ::std::optional<::mlir::OperationName> odsOpName; ::mlir::RegionRange odsRegions; public: - {1}GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) + {1}GenericAdaptorBase(::mlir::DictionaryAttr attrs = {{}, const ::mlir::EmptyProperties &properties = {{}, ::mlir::RegionRange regions = {{}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) odsOpName.emplace("{2}.{0}", odsAttrs.getContext()); } - {1}GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} + {1}GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {{} std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); ::mlir::DictionaryAttr getAttributes() {{ @@ -37,14 +40,14 @@ class {1}GenericAdaptor : public detail::{1}GenericAdaptorBase { using ValueT = ::llvm::detail::ValueOfRange; using Base = detail::{1}GenericAdaptorBase; public: - {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} + {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {{}, const ::mlir::EmptyProperties &properties = {{}, ::mlir::RegionRange regions = {{}) : Base(attrs, properties, regions), odsOperands(values) {{} - {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {}) : {1}GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{}), regions) {} + {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {{}) : {1}GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{{}), regions) {{} - {1}GenericAdaptor(RangeT values, const {1}GenericAdaptorBase &base) : Base(base), odsOperands(values) {} + {1}GenericAdaptor(RangeT values, const {1}GenericAdaptorBase &base) : Base(base), odsOperands(values) {{} template >> - {1}GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} + {1}GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {{} std::pair getODSOperandIndexAndLength(unsigned index) {{ return Base::getODSOperandIndexAndLength(index, odsOperands.size()); @@ -85,14 +88,16 @@ public: using GenericAdaptor = {1}GenericAdaptor; using FoldAdaptor = GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute>>; static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { - return {}; + return {{}; } static constexpr ::llvm::StringLiteral getOperationName() { return ::llvm::StringLiteral("{2}.{0}"); } - std::pair getODSOperandIndexAndLength(unsigned index); + std::pair getODSOperandIndexAndLength(unsigned index) { + return {index, {3}}; + } ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {{std::next(getOperation()->operand_begin(), valueRange.first), @@ -105,7 +110,7 @@ public: ::mlir::MutableOperandRange getArgsMutable(); std::pair getODSResultIndexAndLength(unsigned index) { - return {{index, 1}; + return {{index, {4}}; } ::mlir::Operation::result_range getODSResults(unsigned index) { @@ -119,8 +124,8 @@ public: } static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type output, ::mlir::ValueRange args); - static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); - static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); + static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); std::unique_ptr<::mlir::irdl::Constraint> getVerifier(::mlir::ArrayRef valueToConstr, ::mlir::DenseMap<::mlir::irdl::TypeOp, @@ -132,8 +137,8 @@ public: }; -{4} +{6} -MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({7}::{1}) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index a000c870f4e75..66c503cdc33db 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -6,6 +6,7 @@ {4}: Namespace open {5}: Namespace close +{6}: Namespace path */ R"( @@ -24,5 +25,5 @@ public: {5} -MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({6}::{1}) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index 6e7ffceba1755..0093b07e5b91e 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -3,6 +3,7 @@ {1}: Open namespace {2}: Close namespace +{3}: Namespace path */ @@ -18,5 +19,5 @@ public: {2} -MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::irdl::{0}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({3}::{0}) )" \ No newline at end of file From 8d4bad56187dba9be67933515d0594a34aa75f61 Mon Sep 17 00:00:00 2001 From: --set <--set> Date: Mon, 20 Jan 2025 10:56:12 +0000 Subject: [PATCH 12/94] merged from upstream, added name to mvp --- mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir index 27820a873f72c..b5433311a5d1c 100644 --- a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir +++ b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir @@ -6,7 +6,7 @@ module { irdl.operation @any { %0 = irdl.any - irdl.results(%0) + irdl.results(in1: %0) } } } From 704f1112b51d699db90bf17d4e7be17f8a54fa34 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 20 Jan 2025 13:15:21 +0000 Subject: [PATCH 13/94] return operand names --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 34 ++++++++++++------- .../IRDLToCpp/Templates/OperationDecl.txt | 25 +++++++++----- .../Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 3 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index a1df613f913cf..70a3b247b94a5 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -102,27 +102,37 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto &&block = op.getBody().getBlocks().front(); - const unsigned operandCount = ([&block]() -> unsigned { + auto operandOp = ([&block]() -> std::optional { auto operands = block.getOps(); if (operands.empty()) - return 0; - - // at most 1, guaranteed by verifiers - auto &&operand = *operands.begin(); - return operand.getNumOperands(); + return {}; + return *operands.begin(); })(); - const unsigned resultCount = ([&block]() -> unsigned { - auto resultsOps = block.getOps(); + auto resultsOp = *block.getOps().begin(); + + const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; + + const auto operandNames = ([&operandOp]() -> std::string { + if (!operandOp) + return "{}"; - // exactly 1 resultOp, guaranteed by verifiers - auto &&resultsOp = *resultsOps.begin(); - return resultsOp.getNumOperands(); + auto names = llvm::map_range(operandOp->getNames(), [](auto &attr) { + return mlir::cast(attr); + }); + + std::string nameArray; + llvm::raw_string_ostream nameArrayStream(nameArray); + nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; + + return nameArray; })(); + const unsigned resultCount = resultsOp.getNumOperands(); + output << llvm::formatv( opDeclTemplateText, opName, opCppName, usefulStrings.dialectName, - operandCount, resultCount, usefulStrings.namespaceOpen, + operandCount, operandNames, resultCount, usefulStrings.namespaceOpen, usefulStrings.namespaceClose, usefulStrings.namespacePath); return success(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt index 467c7bb8e9fe0..144abcf24afcf 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -3,15 +3,16 @@ 1: Operation CppName 2: Dialect Name 3: Operand count -4: Result count +4: Operand names +5: Result count -5: open namespace -6: close namespace -7: namespace path +6: open namespace +7: close namespace +8: namespace path */ R"( -{5} +{6} namespace detail { class {1}GenericAdaptorBase { @@ -95,6 +96,14 @@ public: return ::llvm::StringLiteral("{2}.{0}"); } + ::llvm::ArrayRef getOperandNames() { + return {4}; + } + + ::llvm::StringRef getOperandName(unsigned index) {{ + return getOperandNames()[index]; + } + std::pair getODSOperandIndexAndLength(unsigned index) { return {index, {3}}; } @@ -110,7 +119,7 @@ public: ::mlir::MutableOperandRange getArgsMutable(); std::pair getODSResultIndexAndLength(unsigned index) { - return {{index, {4}}; + return {{index, {5}}; } ::mlir::Operation::result_range getODSResults(unsigned index) { @@ -137,8 +146,8 @@ public: }; -{6} +{7} -MLIR_DECLARE_EXPLICIT_TYPE_ID({7}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({8}::{1}) )" \ No newline at end of file diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir index b5433311a5d1c..6e8ce07a3f097 100644 --- a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir +++ b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir @@ -6,7 +6,8 @@ module { irdl.operation @any { %0 = irdl.any - irdl.results(in1: %0) + irdl.operands(in1: %0, in2: %0) + irdl.results(out1: %0) } } } From d30c976f1690b4e1ea044fc549dd08f92eb4e2b1 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 20 Jan 2025 13:15:21 +0000 Subject: [PATCH 14/94] return operand names --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 40 ++++++++++++------- .../IRDLToCpp/Templates/OperationDecl.txt | 25 ++++++++---- .../Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 3 +- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index a1df613f913cf..42e8d31017dc2 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -102,27 +102,37 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto &&block = op.getBody().getBlocks().front(); - const unsigned operandCount = ([&block]() -> unsigned { + auto operandOp = ([&block]() -> std::optional { auto operands = block.getOps(); if (operands.empty()) - return 0; - - // at most 1, guaranteed by verifiers - auto &&operand = *operands.begin(); - return operand.getNumOperands(); + return {}; + return *operands.begin(); })(); - const unsigned resultCount = ([&block]() -> unsigned { - auto resultsOps = block.getOps(); + auto resultsOp = *block.getOps().begin(); + + const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; + + const auto operandNames = ([&operandOp]() -> std::string { + if (!operandOp) + return "{}"; + + auto names = llvm::map_range(operandOp->getNames(), [](Attribute &attr) { + return mlir::cast(attr); + }); - // exactly 1 resultOp, guaranteed by verifiers - auto &&resultsOp = *resultsOps.begin(); - return resultsOp.getNumOperands(); + std::string nameArray; + llvm::raw_string_ostream nameArrayStream(nameArray); + nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; + + return nameArray; })(); + const unsigned resultCount = resultsOp.getNumOperands(); + output << llvm::formatv( opDeclTemplateText, opName, opCppName, usefulStrings.dialectName, - operandCount, resultCount, usefulStrings.namespaceOpen, + operandCount, operandNames, resultCount, usefulStrings.namespaceOpen, usefulStrings.namespaceClose, usefulStrings.namespacePath); return success(); @@ -144,9 +154,9 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, usefulStrings.namespaceOpen, usefulStrings.namespaceClose, usefulStrings.namespacePath); - auto &®ion = dialect->getRegion(0); - auto &&block = region.getBlocks().front(); - for (auto &&op : block) { + auto ®ion = dialect->getRegion(0); + + for (auto &&op : region.getBlocks().front()) { if (auto typeop = llvm::dyn_cast_or_null(op)) { if (failed(generateTypeInclude(typeop, output, usefulStrings))) return failure(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt index 467c7bb8e9fe0..144abcf24afcf 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -3,15 +3,16 @@ 1: Operation CppName 2: Dialect Name 3: Operand count -4: Result count +4: Operand names +5: Result count -5: open namespace -6: close namespace -7: namespace path +6: open namespace +7: close namespace +8: namespace path */ R"( -{5} +{6} namespace detail { class {1}GenericAdaptorBase { @@ -95,6 +96,14 @@ public: return ::llvm::StringLiteral("{2}.{0}"); } + ::llvm::ArrayRef getOperandNames() { + return {4}; + } + + ::llvm::StringRef getOperandName(unsigned index) {{ + return getOperandNames()[index]; + } + std::pair getODSOperandIndexAndLength(unsigned index) { return {index, {3}}; } @@ -110,7 +119,7 @@ public: ::mlir::MutableOperandRange getArgsMutable(); std::pair getODSResultIndexAndLength(unsigned index) { - return {{index, {4}}; + return {{index, {5}}; } ::mlir::Operation::result_range getODSResults(unsigned index) { @@ -137,8 +146,8 @@ public: }; -{6} +{7} -MLIR_DECLARE_EXPLICIT_TYPE_ID({7}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({8}::{1}) )" \ No newline at end of file diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir index b5433311a5d1c..6e8ce07a3f097 100644 --- a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir +++ b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir @@ -6,7 +6,8 @@ module { irdl.operation @any { %0 = irdl.any - irdl.results(in1: %0) + irdl.operands(in1: %0, in2: %0) + irdl.results(out1: %0) } } } From 3411c33bb78f6615a6971db67492589f1dd7c457 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 20 Jan 2025 13:43:54 +0000 Subject: [PATCH 15/94] revert bad edit --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 42e8d31017dc2..79a852ef9f736 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -117,7 +117,7 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, if (!operandOp) return "{}"; - auto names = llvm::map_range(operandOp->getNames(), [](Attribute &attr) { + auto names = llvm::map_range(operandOp->getNames(), [](auto &attr) { return mlir::cast(attr); }); From 731fd7c82026084aba087ced0fce9e19a31b72d9 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 20 Jan 2025 15:36:10 +0000 Subject: [PATCH 16/94] typedef list + print/parse defs --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 207 ++++++++++++------ .../IRDLToCpp/Templates/OperationDecl.txt | 25 ++- .../IRDLToCpp/Templates/OperationDef.txt | 18 ++ .../Target/IRDLToCpp/Templates/TypeDef.txt | 50 +++++ .../IRDLToCpp/Templates/TypeHeaderDef.txt | 7 + 5 files changed, 238 insertions(+), 69 deletions(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 79a852ef9f736..543bd78c48559 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -53,13 +53,20 @@ constexpr char typeDeclTemplateText[] = #include "Templates/TypeDecl.txt" ; +constexpr char typeDefTemplateText[] = +#include "Templates/TypeDef.txt" + ; constexpr char opDeclTemplateText[] = #include "Templates/OperationDecl.txt" ; +constexpr char opDefTemplateText[] = +#include "Templates/OperationDef.txt" + ; + namespace { -struct UsefulStrings { +struct DialectStrings { StringRef dialectName; StringRef dialectCppName; StringRef dialectCppShortName; @@ -70,31 +77,42 @@ struct UsefulStrings { StringRef namespacePath; }; +struct TypeStrings { + StringRef typeName; + std::string typeCppName; +}; + static std::string capitalize(StringRef str) { return llvm::formatv("{0}{1}", llvm::toUpper(str[0]), str.slice(1, str.size())); } +static TypeStrings getStrings(irdl::TypeOp type) { + TypeStrings strings; + strings.typeName = type.getSymName(); + strings.typeCppName = llvm::formatv("{0}Type", capitalize(strings.typeName)); + return strings; +} + } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, - UsefulStrings &usefulStrings) { + DialectStrings &dialectStrings) { - StringRef typeName = type.getSymName(); - std::string typeCppShortName = capitalize(typeName); - std::string typeCppName = llvm::formatv("{0}Type", typeCppShortName); + auto typeStrings = getStrings(type); output << llvm::formatv( - typeDeclTemplateText, typeName, typeCppName, usefulStrings.dialectName, - usefulStrings.dialectBaseTypeName, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose, usefulStrings.namespacePath); + typeDeclTemplateText, typeStrings.typeName, typeStrings.typeCppName, + dialectStrings.dialectName, dialectStrings.dialectBaseTypeName, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose, + dialectStrings.namespacePath); return success(); } static LogicalResult generateOperationInclude(irdl::OperationOp op, raw_ostream &output, - UsefulStrings &usefulStrings) { + DialectStrings &dialectStrings) { StringRef opName = op.getSymName(); std::string opCppShortName = capitalize(opName); @@ -111,60 +129,59 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto resultsOp = *block.getOps().begin(); - const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; - - const auto operandNames = ([&operandOp]() -> std::string { - if (!operandOp) - return "{}"; - - auto names = llvm::map_range(operandOp->getNames(), [](auto &attr) { - return mlir::cast(attr); - }); + constexpr auto getNames = [](auto op) -> std::string { + auto names = llvm::map_range( + op.getNames(), [](auto &attr) { return mlir::cast(attr); }); std::string nameArray; llvm::raw_string_ostream nameArrayStream(nameArray); nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; return nameArray; - })(); + }; + + const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; + const auto operandNames = operandOp ? getNames(*operandOp) : "{}"; - const unsigned resultCount = resultsOp.getNumOperands(); + const auto resultCount = resultsOp.getNumOperands(); + const auto resultNames = getNames(resultsOp); output << llvm::formatv( - opDeclTemplateText, opName, opCppName, usefulStrings.dialectName, - operandCount, operandNames, resultCount, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose, usefulStrings.namespacePath); + opDeclTemplateText, opName, opCppName, dialectStrings.dialectName, + operandCount, operandNames, resultCount, resultNames, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose, + dialectStrings.namespacePath); return success(); } static LogicalResult generateInclude(irdl::DialectOp dialect, raw_ostream &output, - UsefulStrings &usefulStrings) { + DialectStrings &dialectStrings) { output << "#ifdef " << declarationMacroFlag << "\n#undef " << declarationMacroFlag << "\n"; output << llvm::formatv( - dialectDeclTemplateText, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose, usefulStrings.dialectCppName, - usefulStrings.namespacePath, usefulStrings.dialectName); + dialectDeclTemplateText, dialectStrings.namespaceOpen, + dialectStrings.namespaceClose, dialectStrings.dialectCppName, + dialectStrings.namespacePath, dialectStrings.dialectName); output << llvm::formatv( - typeHeaderDeclTemplateText, usefulStrings.dialectBaseTypeName, - usefulStrings.namespaceOpen, usefulStrings.namespaceClose, - usefulStrings.namespacePath); - - auto ®ion = dialect->getRegion(0); - - for (auto &&op : region.getBlocks().front()) { - if (auto typeop = llvm::dyn_cast_or_null(op)) { - if (failed(generateTypeInclude(typeop, output, usefulStrings))) - return failure(); - } - if (auto operationOp = llvm::dyn_cast_or_null(op)) { - if (failed(generateOperationInclude(operationOp, output, usefulStrings))) - return failure(); - } + typeHeaderDeclTemplateText, dialectStrings.dialectBaseTypeName, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose, + dialectStrings.namespacePath); + + auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); + auto typeOps = dialectBlock.getOps(); + auto operationOps = dialectBlock.getOps(); + + for (auto &&typeOp : typeOps) { + if (failed(generateTypeInclude(typeOp, output, dialectStrings))) + return failure(); + } + for (auto &&operationOp : operationOps) { + if (failed(generateOperationInclude(operationOp, output, dialectStrings))) + return failure(); } output << "#endif // " << declarationMacroFlag << "\n"; @@ -172,24 +189,84 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return success(); } +static LogicalResult +generateTypedefList(mlir::Block &dialectBlock, + llvm::SmallVector &typeNames) { + auto typeOps = dialectBlock.getOps(); + auto range = llvm::map_range( + typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); + typeNames = llvm::SmallVector(range); + return success(); +} + static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, - UsefulStrings &usefulStrings) { + DialectStrings &dialectStrings) { output << "#ifdef " << definitionMacroFlag << "\n#undef " << definitionMacroFlag << "\n"; - output << llvm::formatv(dialectDefTemplateText, usefulStrings.namespaceOpen, - usefulStrings.namespaceClose, - usefulStrings.dialectCppName, - usefulStrings.namespacePath); + output << llvm::formatv(dialectDefTemplateText, dialectStrings.namespaceOpen, + dialectStrings.namespaceClose, + dialectStrings.dialectCppName, + dialectStrings.namespacePath); - output << usefulStrings.namespaceOpen; - output << llvm::formatv(typeHeaderDefTemplateText, - usefulStrings.dialectBaseTypeName, - usefulStrings.dialectCppName); - output << usefulStrings.namespaceClose; + // type header + output << llvm::formatv( + typeHeaderDefTemplateText, dialectStrings.dialectBaseTypeName, + dialectStrings.dialectCppName, dialectStrings.namespaceOpen, + dialectStrings.namespaceClose); + + // get typedef list + auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); + llvm::SmallVector typeNames; + if (failed(generateTypedefList(dialectBlock, typeNames))) + return failure(); - output << "#endif // " << definitionMacroFlag << "\n"; + const auto commaSeparatedTypeList = llvm::join(typeNames, ","); + const auto generatedTypeParser = llvm::formatv( + R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { + return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser) + {0} + .Default([&](llvm::StringRef keyword, llvm::SMLoc) {{ + *mnemonic = keyword; + return std::nullopt; + }); +})", + llvm::join( + llvm::map_range( + typeNames, + [&](llvm::StringRef name) -> std::string { + return llvm::formatv( + R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { + value = {1}::{0}::get(parser.getContext()); + return ::mlir::success(!!value); + }) +)", + name, dialectStrings.namespacePath); + }), + "\n")); + + const auto generatedTypePrinter = llvm::formatv( + R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) { + return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def) + {0} + .Default([](auto) {{ return ::mlir::failure(); }); +})", + llvm::join(llvm::map_range(typeNames, + [&](llvm::StringRef name) -> std::string { + return llvm::formatv( + R"(.Case<{1}::{0}>([&](auto t) { + printer << {1}::{0}::getMnemonic(); + return ::mlir::success(); + }))", + name, dialectStrings.namespacePath); + }), + "\n")); + + output << llvm::formatv(typeDefTemplateText, commaSeparatedTypeList, + generatedTypeParser, generatedTypePrinter, + dialectStrings.dialectCppName, dialectStrings.namespaceOpen, dialectStrings.namespaceClose); + output << "#endif // " << definitionMacroFlag << "\n"; return success(); } @@ -229,21 +306,25 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); - UsefulStrings usefulStrings; - usefulStrings.dialectName = dialectName; - usefulStrings.dialectBaseTypeName = dialectBaseTypeName; - usefulStrings.dialectCppName = cppName; - usefulStrings.dialectCppShortName = cppShortName; - usefulStrings.namespaceOpen = namespaceOpen; - usefulStrings.namespaceClose = namespaceClose; - usefulStrings.namespacePath = namespacePath; + DialectStrings dialectStrings; + dialectStrings.dialectName = dialectName; + dialectStrings.dialectBaseTypeName = dialectBaseTypeName; + dialectStrings.dialectCppName = cppName; + dialectStrings.dialectCppShortName = cppShortName; + dialectStrings.namespaceOpen = namespaceOpen; + dialectStrings.namespaceClose = namespaceClose; + dialectStrings.namespacePath = namespacePath; output << headerTemplateText; - if (failed(generateInclude(dialect, output, usefulStrings))) + auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); + auto typeOps = dialectBlock.getOps(); + auto operationOps = dialectBlock.getOps(); + + if (failed(generateInclude(dialect, output, dialectStrings))) return failure(); - if (failed(generateLib(dialect, output, usefulStrings))) + if (failed(generateLib(dialect, output, dialectStrings))) return failure(); return success(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt index 144abcf24afcf..b8ebc4f3ee81d 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt @@ -5,6 +5,7 @@ 3: Operand count 4: Operand names 5: Result count +6: Result names 6: open namespace 7: close namespace @@ -12,7 +13,7 @@ */ R"( -{6} +{7} namespace detail { class {1}GenericAdaptorBase { @@ -96,14 +97,26 @@ public: return ::llvm::StringLiteral("{2}.{0}"); } - ::llvm::ArrayRef getOperandNames() { - return {4}; + static ::llvm::ArrayRef<::llvm::StringRef> getOperandNames() { + static ::llvm::StringRef operandNames[] = {4}; + return operandNames; } - ::llvm::StringRef getOperandName(unsigned index) {{ + static ::llvm::StringRef getOperandName(unsigned index) {{ + assert(index < {3} && "invalid attribute index"); return getOperandNames()[index]; } + static ::llvm::ArrayRef<::llvm::StringRef> getResultNames() { + static ::llvm::StringRef resultNames[] = {6}; + return resultNames; + } + + static ::llvm::StringRef getResultName(unsigned index) {{ + assert(index < {5} && "invalid attribute index"); + return getResultNames()[index]; + } + std::pair getODSOperandIndexAndLength(unsigned index) { return {index, {3}}; } @@ -146,8 +159,8 @@ public: }; -{7} +{8} -MLIR_DECLARE_EXPLICIT_TYPE_ID({8}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({9}::{1}) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt new file mode 100644 index 0000000000000..eb1f18c97a24b --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt @@ -0,0 +1,18 @@ +/* +0: Operation Name +1: Operation CppName +2: Dialect Name +3: Operand count +4: Operand names +5: Result count +6: Result names + +6: open namespace +7: close namespace +8: namespace path +*/ + +R"( + + +)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt new file mode 100644 index 0000000000000..3f1406bdafbc0 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -0,0 +1,50 @@ +/* +{0}: TypeDef list +{1}: TypeParser function +{2}: TypePrinter function +{3}: Dialect CppName +{4}: Namespace open +{5}: Namespace close +*/ + +R"( +#ifdef GET_TYPEDEF_LIST +#undef GET_TYPEDEF_LIST + +{0} + +#endif // GET_TYPEDEF_LIST + + +#ifdef GET_TYPEDEF_CLASSES +#undef GET_TYPEDEF_CLASSES + +{4} +{1} + +{2} + +/// Parse a type registered to this dialect. +::mlir::Type {3}::parseType(::mlir::DialectAsmParser &parser) const {{ + ::llvm::SMLoc typeLoc = parser.getCurrentLocation(); + ::llvm::StringRef mnemonic; + ::mlir::Type genType; + auto parseResult = generatedTypeParser(parser, &mnemonic, genType); + if (parseResult.has_value()) + return genType; + + parser.emitError(typeLoc) << "unknown type `" + << mnemonic << "` in dialect `" << getNamespace() << "`"; + return {{}; +} +/// Print a type registered to this dialect. +void {3}::printType(::mlir::Type type, + ::mlir::DialectAsmPrinter &printer) const {{ + if (::mlir::succeeded(generatedTypePrinter(type, printer))) + return; + +} + +{5} +#endif // GET_TYPEDEF_CLASSES +)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt index da1d204c4c68a..7889c5f737419 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt @@ -1,10 +1,17 @@ /* {0}: Dialect BaseTypeName {1}: Dialect CppName + +{2}: Namespace open +{3}: Namespace close */ R"( +{2} + bool {0}::classof(Type type) {{ return llvm::isa<{1}>(type.getDialect()); } + +{3} )" From 79d5acbee7d066865fcbd38f01a55bf4081c1c18 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 21 Jan 2025 16:20:26 +0000 Subject: [PATCH 17/94] compile decls and defs for build but rather ugly c++ code because <3 lambdas --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 178 ++++++++++++++---- .../IRDLToCpp/Templates/OperationDef.txt | 25 +-- ...OperationDecl.txt => PerOperationDecl.txt} | 22 +-- .../IRDLToCpp/Templates/PerOperationDef.txt | 56 ++++++ .../Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 2 +- 5 files changed, 225 insertions(+), 58 deletions(-) rename mlir/lib/Target/IRDLToCpp/Templates/{OperationDecl.txt => PerOperationDecl.txt} (85%) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 543bd78c48559..5b0dea396bbb3 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -56,8 +56,12 @@ constexpr char typeDeclTemplateText[] = constexpr char typeDefTemplateText[] = #include "Templates/TypeDef.txt" ; -constexpr char opDeclTemplateText[] = -#include "Templates/OperationDecl.txt" +constexpr char perOpDeclTemplateText[] = +#include "Templates/PerOperationDecl.txt" + ; + +constexpr char perOpDefTemplateText[] = +#include "Templates/PerOperationDef.txt" ; constexpr char opDefTemplateText[] = @@ -82,6 +86,11 @@ struct TypeStrings { std::string typeCppName; }; +struct OpStrings { + StringRef opName; + std::string opCppName; +}; + static std::string capitalize(StringRef str) { return llvm::formatv("{0}{1}", llvm::toUpper(str[0]), str.slice(1, str.size())); @@ -94,12 +103,39 @@ static TypeStrings getStrings(irdl::TypeOp type) { return strings; } +static OpStrings getStrings(irdl::OperationOp type) { + OpStrings strings; + strings.opName = type.getSymName(); + strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); + return strings; +} + +static LogicalResult +generateTypedefList(mlir::Block &dialectBlock, + llvm::SmallVector &typeNames) { + auto typeOps = dialectBlock.getOps(); + auto range = llvm::map_range( + typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); + typeNames = llvm::SmallVector(range); + return success(); +} + +static LogicalResult +generateOpList(mlir::Block &dialectBlock, + llvm::SmallVector &typeNames) { + auto typeOps = dialectBlock.getOps(); + auto range = llvm::map_range( + typeOps, [](auto &&type) { return getStrings(type).opCppName; }); + typeNames = llvm::SmallVector(range); + return success(); +} + } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, DialectStrings &dialectStrings) { - auto typeStrings = getStrings(type); + const auto typeStrings = getStrings(type); output << llvm::formatv( typeDeclTemplateText, typeStrings.typeName, typeStrings.typeCppName, @@ -114,41 +150,45 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, raw_ostream &output, DialectStrings &dialectStrings) { - StringRef opName = op.getSymName(); - std::string opCppShortName = capitalize(opName); - std::string opCppName = llvm::formatv("{0}Op", opCppShortName); + const auto opStrings = getStrings(op); - auto &&block = op.getBody().getBlocks().front(); + auto &block = op.getBody().getBlocks().front(); - auto operandOp = ([&block]() -> std::optional { - auto operands = block.getOps(); - if (operands.empty()) - return {}; - return *operands.begin(); - })(); + auto operands = block.getOps(); + auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); auto resultsOp = *block.getOps().begin(); - constexpr auto getNames = [](auto op) -> std::string { + constexpr auto getNames = [](auto op) { auto names = llvm::map_range( op.getNames(), [](auto &attr) { return mlir::cast(attr); }); + return names; + }; + constexpr auto stringify = [](auto&& names) -> std::string { std::string nameArray; llvm::raw_string_ostream nameArrayStream(nameArray); nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; return nameArray; + }; const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; - const auto operandNames = operandOp ? getNames(*operandOp) : "{}"; + const auto operandNames = operandOp ? stringify(getNames(*operandOp)) : "{}"; const auto resultCount = resultsOp.getNumOperands(); - const auto resultNames = getNames(resultsOp); + const auto resultAttrArray = getNames(resultsOp); + const auto resultNames = stringify(resultAttrArray); + + const auto buildDeclaration = llvm::formatv(R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)" + , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Type {0}, ", attr); }), "") + , llvm::join(llvm::map_range(getNames(*operandOp), [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Value {0}, ", attr); }), "") + ); output << llvm::formatv( - opDeclTemplateText, opName, opCppName, dialectStrings.dialectName, - operandCount, operandNames, resultCount, resultNames, + perOpDeclTemplateText, opStrings.opName, opStrings.opCppName, dialectStrings.dialectName, + operandCount, operandNames, resultCount, resultNames, buildDeclaration, dialectStrings.namespaceOpen, dialectStrings.namespaceClose, dialectStrings.namespacePath); @@ -179,6 +219,22 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, if (failed(generateTypeInclude(typeOp, output, dialectStrings))) return failure(); } + + llvm::SmallVector opNames; + if (failed(generateOpList(dialectBlock, opNames))) + return failure(); + const auto forwardDeclarations = llvm::formatv( + R"( +{1} +{0} +{2} + )", + llvm::join(llvm::map_range(opNames, [](llvm::StringRef name) -> std::string { return llvm::formatv("class {0};", name);}), "\n"), + dialectStrings.namespaceOpen, + dialectStrings.namespaceClose + ); + + output << forwardDeclarations; for (auto &&operationOp : operationOps) { if (failed(generateOperationInclude(operationOp, output, dialectStrings))) return failure(); @@ -189,15 +245,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return success(); } -static LogicalResult -generateTypedefList(mlir::Block &dialectBlock, - llvm::SmallVector &typeNames) { - auto typeOps = dialectBlock.getOps(); - auto range = llvm::map_range( - typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); - typeNames = llvm::SmallVector(range); - return success(); -} static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { @@ -221,7 +268,8 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, if (failed(generateTypedefList(dialectBlock, typeNames))) return failure(); - const auto commaSeparatedTypeList = llvm::join(typeNames, ","); + const auto commaSeparatedTypeList = llvm::join(llvm::map_range(typeNames, [&dialectStrings](llvm::StringRef name) -> std::string + { return llvm::formatv("{0}::{1}", dialectStrings.namespacePath, name); }), ",\n"); const auto generatedTypeParser = llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { @@ -240,8 +288,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { value = {1}::{0}::get(parser.getContext()); return ::mlir::success(!!value); - }) -)", + }))", name, dialectStrings.namespacePath); }), "\n")); @@ -266,6 +313,73 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, output << llvm::formatv(typeDefTemplateText, commaSeparatedTypeList, generatedTypeParser, generatedTypePrinter, dialectStrings.dialectCppName, dialectStrings.namespaceOpen, dialectStrings.namespaceClose); + + + // get op list + auto operations = dialectBlock.getOps(); + llvm::SmallVector opNames; + if (failed(generateOpList(dialectBlock, opNames))) + return failure(); + const auto commaSeparatedOpList = llvm::join(llvm::map_range(opNames, [&dialectStrings](llvm::StringRef name) -> std::string + { return llvm::formatv("{0}::{1}", dialectStrings.namespacePath, name); }), ",\n"); + + const auto perOpDefinitions = llvm::join(llvm::map_range(operations, [&dialectStrings](irdl::OperationOp op) -> std::string { + auto opStrings = getStrings(op); + + auto &block = op.getBody().getBlocks().front(); + + auto operands = block.getOps(); + auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); + + auto resultsOp = *block.getOps().begin(); + + constexpr auto getNames = [](auto op) { + auto names = llvm::map_range( + op.getNames(), [](auto &attr) { return mlir::cast(attr); }); + return names; + }; + + constexpr auto stringify = [](auto&& names) -> std::string { + std::string nameArray; + llvm::raw_string_ostream nameArrayStream(nameArray); + nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; + + return nameArray; + + }; + + const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; + const auto operandAttrArray = getNames(*operandOp); + const auto operandNames = operandOp ? stringify(getNames(*operandOp)) : "{}"; + + const auto resultCount = resultsOp.getNumOperands(); + const auto resultAttrArray = getNames(resultsOp); + const auto resultNames = stringify(resultAttrArray); + + const auto buildDefinition = llvm::formatv(R"( +static void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ +{3} +{4} +} + )" + , opStrings.opCppName + , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Type {0}, ", attr); }), "") + , llvm::join(llvm::map_range(operandAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Value {0}, ", attr); }), "") + , llvm::join(llvm::map_range(operandAttrArray, [](::mlir::StringAttr attr) -> std::string { + return llvm::formatv(" odsBuilder.addOperands({0});", attr); + }), "\n") + , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { + return llvm::formatv(" odsBuilder.addTypes({0});", attr); + }), "\n") + ); + return llvm::formatv(perOpDefTemplateText, opStrings.opName, opStrings.opCppName, dialectStrings.dialectName, + operandCount, operandNames, resultCount, resultNames, buildDefinition, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose, + dialectStrings.namespacePath); + }), "\n"); + + output << llvm::formatv(opDefTemplateText, commaSeparatedOpList, perOpDefinitions); + output << "#endif // " << definitionMacroFlag << "\n"; return success(); } @@ -317,10 +431,6 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, output << headerTemplateText; - auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); - auto typeOps = dialectBlock.getOps(); - auto operationOps = dialectBlock.getOps(); - if (failed(generateInclude(dialect, output, dialectStrings))) return failure(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt index eb1f18c97a24b..ba795083ac45e 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt @@ -1,18 +1,21 @@ /* -0: Operation Name -1: Operation CppName -2: Dialect Name -3: Operand count -4: Operand names -5: Result count -6: Result names - -6: open namespace -7: close namespace -8: namespace path +{0}: Comma-separated op list +{2}: Per-op definitions */ R"( +#ifdef GET_OP_LIST +#undef GET_OP_LIST + +{0} + +#endif // GET_OP_LIST + + +#ifdef GET_OP_CLASSES +#undef GET_OP_CLASSES +{1} +#endif // GET_OP_CLASSES )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt similarity index 85% rename from mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt rename to mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index b8ebc4f3ee81d..5c9f048f9904d 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -6,14 +6,15 @@ 4: Operand names 5: Result count 6: Result names +7: Build declarations -6: open namespace -7: close namespace -8: namespace path +8: open namespace +9: close namespace +10: namespace path */ R"( -{7} +{8} namespace detail { class {1}GenericAdaptorBase { @@ -145,22 +146,19 @@ public: return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); } - static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type output, ::mlir::ValueRange args); - static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); - static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); + {7} + static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); + ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); - std::unique_ptr<::mlir::irdl::Constraint> getVerifier(::mlir::ArrayRef valueToConstr, ::mlir::DenseMap<::mlir::irdl::TypeOp, - std::unique_ptr<::mlir::DynamicTypeDefinition>> const&types, ::mlir::DenseMap<::mlir::irdl::AttributeOp, - std::unique_ptr<::mlir::DynamicAttrDefinition>> const&attrs); static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); void print(::mlir::OpAsmPrinter &_odsPrinter); public: }; -{8} +{9} -MLIR_DECLARE_EXPLICIT_TYPE_ID({9}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID({10}::{1}) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt new file mode 100644 index 0000000000000..953b62c928d63 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -0,0 +1,56 @@ +/* +0: Operation Name +1: Operation CppName +2: Dialect Name +3: Operand count +4: Operand names +5: Result count +6: Result names +7: Build definitions + +8: open namespace +9: close namespace +10: namespace path +*/ + +R"( + +//===----------------------------------------------------------------------===// +// {10}::{1} definitions +//===----------------------------------------------------------------------===// + +{8} + +::llvm::LogicalResult {1}::verifyInvariantsImpl() {{ + return ::mlir::success(); +} + +::llvm::LogicalResult {1}::verifyInvariants() {{ + return verifyInvariantsImpl(); +} + +::mlir::ParseResult {1}::parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result) {{ + assert(false && "not implemented"); + return ::mlir::failure(); +} + +{7} + +void {1}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ + assert(operands.size() == {3}); + assert(resultTypes.size() == {5}); + odsBuilder.addOperands(operands); + odsBuilder.addAttributes(attributes); + odsBuilder.addTypes(resultTypes); +} + + + +void {1}::print(::mlir::OpAsmPrinter &_odsPrinter) {{ + assert(false && "not implemented"); +} + +{9} + +MLIR_DEFINE_EXPLICIT_TYPE_ID({10}::{1}) +)" \ No newline at end of file diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir index 6e8ce07a3f097..0bfdac52dde49 100644 --- a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir +++ b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir @@ -4,7 +4,7 @@ module { irdl.dialect @testd { irdl.type @singleton - irdl.operation @any { + irdl.operation @foo { %0 = irdl.any irdl.operands(in1: %0, in2: %0) irdl.results(out1: %0) From 02d396ede6230902a3f386800e25004d33e32fb0 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 21 Jan 2025 22:27:42 +0000 Subject: [PATCH 18/94] refactored name processing logic --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 248 ++++++++++++++---------- 1 file changed, 148 insertions(+), 100 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 5b0dea396bbb3..569c5316e932f 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -89,6 +89,8 @@ struct TypeStrings { struct OpStrings { StringRef opName; std::string opCppName; + llvm::SmallVector opResultNames; + llvm::SmallVector opOperandNames; }; static std::string capitalize(StringRef str) { @@ -103,10 +105,40 @@ static TypeStrings getStrings(irdl::TypeOp type) { return strings; } -static OpStrings getStrings(irdl::OperationOp type) { +static OpStrings getStrings(irdl::OperationOp op) { + + auto &block = op.getBody().getBlocks().front(); + + auto operands = block.getOps(); + auto operandOp = + operands.empty() ? std::optional{} : *operands.begin(); + + auto resultsOp = *block.getOps().begin(); + + constexpr auto getNames = [](auto op) { + auto names = llvm::map_range( + op.getNames(), [](auto &attr) { return mlir::cast(attr); }); + return names; + }; + + const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; + + const auto resultCount = resultsOp.getNumOperands(); + const auto resultAttrArray = getNames(resultsOp); + OpStrings strings; - strings.opName = type.getSymName(); + strings.opName = op.getSymName(); strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); + if (operandOp) + strings.opOperandNames = llvm::SmallVector( + llvm::map_range(operandOp->getNames(), [](Attribute attr) { + return llvm::formatv("{0}", cast(attr)); + })); + strings.opResultNames = llvm::SmallVector( + llvm::map_range(resultsOp.getNames(), [](Attribute attr) { + return llvm::formatv("{0}", cast(attr)); + })); + return strings; } @@ -120,9 +152,8 @@ generateTypedefList(mlir::Block &dialectBlock, return success(); } -static LogicalResult -generateOpList(mlir::Block &dialectBlock, - llvm::SmallVector &typeNames) { +static LogicalResult generateOpList(mlir::Block &dialectBlock, + llvm::SmallVector &typeNames) { auto typeOps = dialectBlock.getOps(); auto range = llvm::map_range( typeOps, [](auto &&type) { return getStrings(type).opCppName; }); @@ -152,45 +183,41 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto opStrings = getStrings(op); - auto &block = op.getBody().getBlocks().front(); - - auto operands = block.getOps(); - auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); - - auto resultsOp = *block.getOps().begin(); - - constexpr auto getNames = [](auto op) { - auto names = llvm::map_range( - op.getNames(), [](auto &attr) { return mlir::cast(attr); }); - return names; - }; - - constexpr auto stringify = [](auto&& names) -> std::string { + constexpr auto stringify = [](auto &&names) -> std::string { std::string nameArray; llvm::raw_string_ostream nameArrayStream(nameArray); nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; return nameArray; - }; - const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; - const auto operandNames = operandOp ? stringify(getNames(*operandOp)) : "{}"; + const auto operandCount = opStrings.opOperandNames.size(); + const auto operandNames = + operandCount ? stringify(opStrings.opOperandNames) : "{}"; - const auto resultCount = resultsOp.getNumOperands(); - const auto resultAttrArray = getNames(resultsOp); - const auto resultNames = stringify(resultAttrArray); + const auto resultCount = opStrings.opResultNames.size(); + const auto resultNames = stringify(opStrings.opResultNames); - const auto buildDeclaration = llvm::formatv(R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)" - , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Type {0}, ", attr); }), "") - , llvm::join(llvm::map_range(getNames(*operandOp), [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Value {0}, ", attr); }), "") - ); + const auto buildDeclaration = llvm::formatv( + R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", + llvm::join(llvm::map_range(opStrings.opResultNames, + [](StringRef name) -> std::string { + return llvm::formatv("::mlir::Type {0}, ", + name); + }), + ""), + llvm::join(llvm::map_range(opStrings.opOperandNames, + [](StringRef name) -> std::string { + return llvm::formatv("::mlir::Value {0}, ", + name); + }), + "")); output << llvm::formatv( - perOpDeclTemplateText, opStrings.opName, opStrings.opCppName, dialectStrings.dialectName, - operandCount, operandNames, resultCount, resultNames, buildDeclaration, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose, - dialectStrings.namespacePath); + perOpDeclTemplateText, opStrings.opName, opStrings.opCppName, + dialectStrings.dialectName, operandCount, operandNames, resultCount, + resultNames, buildDeclaration, dialectStrings.namespaceOpen, + dialectStrings.namespaceClose, dialectStrings.namespacePath); return success(); } @@ -224,15 +251,17 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, if (failed(generateOpList(dialectBlock, opNames))) return failure(); const auto forwardDeclarations = llvm::formatv( - R"( + R"( {1} {0} {2} )", - llvm::join(llvm::map_range(opNames, [](llvm::StringRef name) -> std::string { return llvm::formatv("class {0};", name);}), "\n"), - dialectStrings.namespaceOpen, - dialectStrings.namespaceClose - ); + llvm::join(llvm::map_range(opNames, + [](llvm::StringRef name) -> std::string { + return llvm::formatv("class {0};", name); + }), + "\n"), + dialectStrings.namespaceOpen, dialectStrings.namespaceClose); output << forwardDeclarations; for (auto &&operationOp : operationOps) { @@ -245,7 +274,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return success(); } - static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { output << "#ifdef " << definitionMacroFlag << "\n#undef " @@ -268,8 +296,13 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, if (failed(generateTypedefList(dialectBlock, typeNames))) return failure(); - const auto commaSeparatedTypeList = llvm::join(llvm::map_range(typeNames, [&dialectStrings](llvm::StringRef name) -> std::string - { return llvm::formatv("{0}::{1}", dialectStrings.namespacePath, name); }), ",\n"); + const auto commaSeparatedTypeList = llvm::join( + llvm::map_range(typeNames, + [&dialectStrings](llvm::StringRef name) -> std::string { + return llvm::formatv( + "{0}::{1}", dialectStrings.namespacePath, name); + }), + ",\n"); const auto generatedTypeParser = llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { @@ -310,75 +343,90 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), "\n")); - output << llvm::formatv(typeDefTemplateText, commaSeparatedTypeList, - generatedTypeParser, generatedTypePrinter, - dialectStrings.dialectCppName, dialectStrings.namespaceOpen, dialectStrings.namespaceClose); - + output << llvm::formatv( + typeDefTemplateText, commaSeparatedTypeList, generatedTypeParser, + generatedTypePrinter, dialectStrings.dialectCppName, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose); // get op list auto operations = dialectBlock.getOps(); llvm::SmallVector opNames; if (failed(generateOpList(dialectBlock, opNames))) return failure(); - const auto commaSeparatedOpList = llvm::join(llvm::map_range(opNames, [&dialectStrings](llvm::StringRef name) -> std::string - { return llvm::formatv("{0}::{1}", dialectStrings.namespacePath, name); }), ",\n"); - - const auto perOpDefinitions = llvm::join(llvm::map_range(operations, [&dialectStrings](irdl::OperationOp op) -> std::string { - auto opStrings = getStrings(op); - - auto &block = op.getBody().getBlocks().front(); - - auto operands = block.getOps(); - auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); - - auto resultsOp = *block.getOps().begin(); - - constexpr auto getNames = [](auto op) { - auto names = llvm::map_range( - op.getNames(), [](auto &attr) { return mlir::cast(attr); }); - return names; - }; - - constexpr auto stringify = [](auto&& names) -> std::string { - std::string nameArray; - llvm::raw_string_ostream nameArrayStream(nameArray); - nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; - - return nameArray; - - }; - - const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; - const auto operandAttrArray = getNames(*operandOp); - const auto operandNames = operandOp ? stringify(getNames(*operandOp)) : "{}"; - - const auto resultCount = resultsOp.getNumOperands(); - const auto resultAttrArray = getNames(resultsOp); - const auto resultNames = stringify(resultAttrArray); - - const auto buildDefinition = llvm::formatv(R"( + const auto commaSeparatedOpList = llvm::join( + llvm::map_range(opNames, + [&dialectStrings](llvm::StringRef name) -> std::string { + return llvm::formatv( + "{0}::{1}", dialectStrings.namespacePath, name); + }), + ",\n"); + + const auto perOpDefinitions = llvm::join( + llvm::map_range( + operations, + [&dialectStrings](irdl::OperationOp op) -> std::string { + auto opStrings = getStrings(op); + + constexpr auto stringify = [](auto &&names) -> std::string { + std::string nameArray; + llvm::raw_string_ostream nameArrayStream(nameArray); + nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; + + return nameArray; + }; + + const auto operandCount = opStrings.opOperandNames.size(); + const auto operandNames = + operandCount ? stringify(opStrings.opOperandNames) : "{}"; + + const auto resultCount = opStrings.opResultNames.size(); + const auto resultNames = stringify(opStrings.opResultNames); + + const auto buildDefinition = llvm::formatv( + R"( static void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ {3} {4} } - )" - , opStrings.opCppName - , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Type {0}, ", attr); }), "") - , llvm::join(llvm::map_range(operandAttrArray, [](::mlir::StringAttr attr) -> std::string { return llvm::formatv("::mlir::Value {0}, ", attr); }), "") - , llvm::join(llvm::map_range(operandAttrArray, [](::mlir::StringAttr attr) -> std::string { - return llvm::formatv(" odsBuilder.addOperands({0});", attr); - }), "\n") - , llvm::join(llvm::map_range(resultAttrArray, [](::mlir::StringAttr attr) -> std::string { - return llvm::formatv(" odsBuilder.addTypes({0});", attr); - }), "\n") - ); - return llvm::formatv(perOpDefTemplateText, opStrings.opName, opStrings.opCppName, dialectStrings.dialectName, - operandCount, operandNames, resultCount, resultNames, buildDefinition, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose, - dialectStrings.namespacePath); - }), "\n"); - - output << llvm::formatv(opDefTemplateText, commaSeparatedOpList, perOpDefinitions); + )", + opStrings.opCppName, + llvm::join(llvm::map_range(opStrings.opResultNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + "::mlir::Type {0}, ", attr); + }), + ""), + llvm::join(llvm::map_range(opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + "::mlir::Value {0}, ", attr); + }), + ""), + llvm::join(llvm::map_range( + opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " odsBuilder.addOperands({0});", attr); + }), + "\n"), + llvm::join(llvm::map_range(opStrings.opResultNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " odsBuilder.addTypes({0});", + attr); + }), + "\n")); + return llvm::formatv( + perOpDefTemplateText, opStrings.opName, opStrings.opCppName, + dialectStrings.dialectName, operandCount, operandNames, + resultCount, resultNames, buildDefinition, + dialectStrings.namespaceOpen, dialectStrings.namespaceClose, + dialectStrings.namespacePath); + }), + "\n"); + + output << llvm::formatv(opDefTemplateText, commaSeparatedOpList, + perOpDefinitions); output << "#endif // " << definitionMacroFlag << "\n"; return success(); From 3ddd47bf994d4dbcc0e8357d504607fbd9e684bd Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Wed, 22 Jan 2025 10:07:54 +0000 Subject: [PATCH 19/94] define typeIDs --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 6 +++++- mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 569c5316e932f..8a0deeaf4e408 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -343,9 +343,13 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), "\n")); + const auto typeIdDefinitions = llvm::join(llvm::map_range(typeNames, [&](StringRef name) -> std::string { + return llvm::formatv("MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", name, dialectStrings.namespacePath); + }), "\n"); + output << llvm::formatv( typeDefTemplateText, commaSeparatedTypeList, generatedTypeParser, - generatedTypePrinter, dialectStrings.dialectCppName, + generatedTypePrinter, dialectStrings.dialectCppName, typeIdDefinitions, dialectStrings.namespaceOpen, dialectStrings.namespaceClose); // get op list diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index 3f1406bdafbc0..3f8afff2fbe25 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -3,8 +3,9 @@ {1}: TypeParser function {2}: TypePrinter function {3}: Dialect CppName -{4}: Namespace open -{5}: Namespace close +{4}: TypeID Defines +{5}: Namespace open +{6}: Namespace close */ R"( @@ -20,6 +21,9 @@ R"( #undef GET_TYPEDEF_CLASSES {4} + +{5} + {1} {2} @@ -45,6 +49,6 @@ void {3}::printType(::mlir::Type type, } -{5} +{6} #endif // GET_TYPEDEF_CLASSES )" \ No newline at end of file From f6920fe600967d68527eeb607f9923d1e9b85f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= <30992420+Moxinilian@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:39:41 +0100 Subject: [PATCH 20/94] irdl-to-cpp toolchain (#16) * first draft of irdl-to-cpp toolchain * basic mlir-irdl-to-cpp tool * it works!! --- mlir/CMakeLists.txt | 1 + mlir/cmake/modules/CMakeLists.txt | 3 + mlir/cmake/modules/IRDLToCpp.cmake | 9 ++ mlir/cmake/modules/MLIRConfig.cmake.in | 1 + mlir/test/lib/Dialect/CMakeLists.txt | 1 + .../lib/Dialect/TestIRDLToCpp/CMakeLists.txt | 13 +++ .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 0 .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 1 + mlir/tools/CMakeLists.txt | 1 + mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt | 7 ++ .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 94 +++++++++++++++++++ 11 files changed, 131 insertions(+) create mode 100644 mlir/cmake/modules/IRDLToCpp.cmake create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir create mode 100644 mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt create mode 100644 mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 9e786154a2b40..8a9d4a98f20da 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -63,6 +63,7 @@ list(INSERT CMAKE_MODULE_PATH 0 ) include(AddMLIR) +include(IRDLToCpp) # -BSymbolic is incompatible with TypeID if("${CMAKE_SHARED_LINKER_FLAGS}" MATCHES "-Bsymbolic[^-]") diff --git a/mlir/cmake/modules/CMakeLists.txt b/mlir/cmake/modules/CMakeLists.txt index 3ac1c79b090ed..054379706c869 100644 --- a/mlir/cmake/modules/CMakeLists.txt +++ b/mlir/cmake/modules/CMakeLists.txt @@ -80,6 +80,8 @@ set(MLIR_CONFIG_TABLEGEN_EXE mlir-tblgen) set(MLIR_CONFIG_PDLL_TABLEGEN_EXE mlir-pdll) set(MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE mlir-src-sharder) +set(MLIR_CONFIG_IRDL_TO_CPP_EXE mlir-irdl-to-cpp) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/MLIRConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MLIRConfig.cmake @@ -103,6 +105,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MLIRConfigVersion.cmake ${CMAKE_CURRENT_SOURCE_DIR}/AddMLIR.cmake ${CMAKE_CURRENT_SOURCE_DIR}/AddMLIRPython.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/IRDLToCpp.cmake ${CMAKE_CURRENT_SOURCE_DIR}/MLIRDetectPythonEnv.cmake DESTINATION ${MLIR_INSTALL_PACKAGE_DIR} COMPONENT mlir-cmake-exports) diff --git a/mlir/cmake/modules/IRDLToCpp.cmake b/mlir/cmake/modules/IRDLToCpp.cmake new file mode 100644 index 0000000000000..651e115e86357 --- /dev/null +++ b/mlir/cmake/modules/IRDLToCpp.cmake @@ -0,0 +1,9 @@ +function(add_irdl_to_cpp_target target irdl_file) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${irdl_file} -o ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc + DEPENDS mlir-irdl-to-cpp ${irdl_file} + COMMENT "Building ${irdl_file}..." + ) + add_custom_target(${target} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc) +endfunction() diff --git a/mlir/cmake/modules/MLIRConfig.cmake.in b/mlir/cmake/modules/MLIRConfig.cmake.in index 7076d94a32f2b..114cb61ed6f55 100644 --- a/mlir/cmake/modules/MLIRConfig.cmake.in +++ b/mlir/cmake/modules/MLIRConfig.cmake.in @@ -12,6 +12,7 @@ set(MLIR_INCLUDE_DIRS "@MLIR_CONFIG_INCLUDE_DIRS@") set(MLIR_TABLEGEN_EXE "@MLIR_CONFIG_TABLEGEN_EXE@") set(MLIR_PDLL_TABLEGEN_EXE "@MLIR_CONFIG_PDLL_TABLEGEN_EXE@") set(MLIR_SRC_SHARDER_TABLEGEN_EXE "@MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE@") +set(MLIR_IRDL_TO_CPP_EXE "@MLIR_CONFIG_IRDL_TO_CPP_EXE@") set(MLIR_INSTALL_AGGREGATE_OBJECTS "@MLIR_INSTALL_AGGREGATE_OBJECTS@") set(MLIR_ENABLE_BINDINGS_PYTHON "@MLIR_ENABLE_BINDINGS_PYTHON@") set(MLIR_ENABLE_EXECUTION_ENGINE "@MLIR_ENABLE_EXECUTION_ENGINE@") diff --git a/mlir/test/lib/Dialect/CMakeLists.txt b/mlir/test/lib/Dialect/CMakeLists.txt index 29fb4441a24fd..b14448099e0c5 100644 --- a/mlir/test/lib/Dialect/CMakeLists.txt +++ b/mlir/test/lib/Dialect/CMakeLists.txt @@ -19,6 +19,7 @@ add_subdirectory(SPIRV) add_subdirectory(Tensor) add_subdirectory(Test) add_subdirectory(TestDyn) +add_subdirectory(TestIRDLToCpp) add_subdirectory(Tosa) add_subdirectory(Transform) add_subdirectory(Vector) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt b/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt new file mode 100644 index 0000000000000..c3ee76f4b9e71 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt @@ -0,0 +1,13 @@ +add_irdl_to_cpp_target(TestIRDLToCppGen test_irdl_to_cpp.irdl.mlir) + +add_mlir_library(MLIRTestIRDLToCppDialect + TestIRDLToCppDialect.cpp + + EXCLUDE_FROM_LIBMLIR + + DEPENDS + TestIRDLToCppGen + + LINK_LIBS PUBLIC + MLIRIR +) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir new file mode 100644 index 0000000000000..48caa8c89ce6f --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -0,0 +1 @@ +irdl.dialect @test_irdl_to_cpp {} diff --git a/mlir/tools/CMakeLists.txt b/mlir/tools/CMakeLists.txt index 072e83c5d45ea..93e8ebb117581 100644 --- a/mlir/tools/CMakeLists.txt +++ b/mlir/tools/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(mlir-irdl-to-cpp) add_subdirectory(mlir-lsp-server) add_subdirectory(mlir-opt) add_subdirectory(mlir-parser-fuzzer) diff --git a/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt b/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt new file mode 100644 index 0000000000000..36bdfc58af015 --- /dev/null +++ b/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt @@ -0,0 +1,7 @@ +add_mlir_tool(mlir-irdl-to-cpp + mlir-irdl-to-cpp.cpp + ) +mlir_target_link_libraries(mlir-irdl-to-cpp + PRIVATE + MLIRTargetIRDLToCpp + ) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp new file mode 100644 index 0000000000000..5e0ee6c161a41 --- /dev/null +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -0,0 +1,94 @@ +//===- mlir-irdl-to-cpp.cpp - IRDL to C++ conversion tool -----------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This is a command line utility that translates an IRDL dialect definition +// into a C++ implementation to be included in MLIR. +// +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/IRDL/IR/IRDL.h" +#include "mlir/IR/AsmState.h" +#include "mlir/IR/DialectRegistry.h" +#include "mlir/IR/MLIRContext.h" +#include "mlir/Support/FileUtilities.h" +#include "mlir/Support/ToolUtilities.h" +#include "mlir/Target/IRDLToCpp/IRDLToCpp.h" +#include "mlir/Tools/ParseUtilities.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/ToolOutputFile.h" + +using namespace mlir; + +static LogicalResult translateIRDLToCpp(int argc, char **argv) { + static llvm::cl::opt inputFilename( + llvm::cl::Positional, llvm::cl::desc(""), + llvm::cl::init("-")); + + static llvm::cl::opt outputFilename( + "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), + llvm::cl::init("-")); + + llvm::InitLLVM y(argc, argv); + + llvm::cl::ParseCommandLineOptions(argc, argv, "mlir-irdl-to-cpp"); + + std::string errorMessage; + std::unique_ptr input = + openInputFile(inputFilename, &errorMessage); + if (!input) { + llvm::errs() << errorMessage << "\n"; + return failure(); + } + + std::unique_ptr output = + openOutputFile(outputFilename, &errorMessage); + if (!output) { + llvm::errs() << errorMessage << "\n"; + return failure(); + } + + auto sourceMgr = std::make_shared(); + sourceMgr->AddNewSourceBuffer(std::move(input), SMLoc()); + + DialectRegistry registry; + registry.insert(); + MLIRContext ctx(registry); + ctx.printOpOnDiagnostic(true); + + ParserConfig parseConfig(&ctx); + OwningOpRef op = + parseSourceFileForTool(sourceMgr, parseConfig, true); + if (!op) + return failure(); + + auto moduleOp = llvm::cast(*op); + + SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); + + for (Operation &op : moduleOp.getOps()) { + auto dialectOp = llvm::dyn_cast(op); + if (!dialectOp) + continue; + + // TODO: accept multiple operations in translation to not generate headers + // multiple times. + if (failed(irdl::translateIRDLDialectToCpp(dialectOp, output->os()))) + return failure(); + } + + output->keep(); + return success(); +} + +int main(int argc, char **argv) { + return failed(translateIRDLToCpp(argc, argv)); +} From 69ee9b0d9bdfd0d0380489f2bbd92affcfc60b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= <30992420+Moxinilian@users.noreply.github.com> Date: Sun, 26 Jan 2025 01:25:39 +0100 Subject: [PATCH 21/94] add cross-compile support (#17) --- mlir/CMakeLists.txt | 1 + mlir/cmake/modules/IRDLToCpp.cmake | 4 ++-- mlir/tools/CMakeLists.txt | 1 - mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt | 23 +++++++++++++++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 8a9d4a98f20da..56e756d4ae55c 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -207,6 +207,7 @@ include_directories(BEFORE # Adding tools/mlir-tblgen here as calling add_tablegen sets some variables like # MLIR_TABLEGEN_EXE in PARENT_SCOPE which gets lost if that folder is included # from another directory like tools +add_subdirectory(tools/mlir-irdl-to-cpp) add_subdirectory(tools/mlir-linalg-ods-gen) add_subdirectory(tools/mlir-pdll) add_subdirectory(tools/mlir-tblgen) diff --git a/mlir/cmake/modules/IRDLToCpp.cmake b/mlir/cmake/modules/IRDLToCpp.cmake index 651e115e86357..8365f5fd8bfe0 100644 --- a/mlir/cmake/modules/IRDLToCpp.cmake +++ b/mlir/cmake/modules/IRDLToCpp.cmake @@ -1,8 +1,8 @@ function(add_irdl_to_cpp_target target irdl_file) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc - COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${irdl_file} -o ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc - DEPENDS mlir-irdl-to-cpp ${irdl_file} + COMMAND ${MLIR_IRDL_TO_CPP_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/${irdl_file} -o ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc + DEPENDS ${MLIR_IRDL_TO_CPP_TARGET} ${irdl_file} COMMENT "Building ${irdl_file}..." ) add_custom_target(${target} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc) diff --git a/mlir/tools/CMakeLists.txt b/mlir/tools/CMakeLists.txt index 93e8ebb117581..072e83c5d45ea 100644 --- a/mlir/tools/CMakeLists.txt +++ b/mlir/tools/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(mlir-irdl-to-cpp) add_subdirectory(mlir-lsp-server) add_subdirectory(mlir-opt) add_subdirectory(mlir-parser-fuzzer) diff --git a/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt b/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt index 36bdfc58af015..3a0f77d856b44 100644 --- a/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt +++ b/mlir/tools/mlir-irdl-to-cpp/CMakeLists.txt @@ -1,7 +1,28 @@ -add_mlir_tool(mlir-irdl-to-cpp +add_llvm_executable(mlir-irdl-to-cpp mlir-irdl-to-cpp.cpp ) mlir_target_link_libraries(mlir-irdl-to-cpp PRIVATE MLIRTargetIRDLToCpp ) + +# Set up a native build when cross-compiling. +if(LLVM_USE_HOST_TOOLS) + build_native_tool( + mlir-irdl-to-cpp + MLIR_IRDL_TO_CPP_EXE + + # Native tool must depend on target tool so that the native tool gets + # properly rebuilt when the target tool changes. + DEPENDS mlir-irdl-to-cpp + ) + add_custom_target(mlir-irdl-to-cpp-host DEPENDS ${MLIR_IRDL_TO_CPP_EXE}) + set(MLIR_IRDL_TO_CPP_TARGET mlir-irdl-to-cpp-host) +else() + set(MLIR_IRDL_TO_CPP_EXE $) + set(MLIR_IRDL_TO_CPP_TARGET mlir-irdl-to-cpp) +endif() + +# Save the executable path and target name to the cache to expose it globally. +set(MLIR_IRDL_TO_CPP_EXE "${MLIR_IRDL_TO_CPP_EXE}" CACHE INTERNAL "") +set(MLIR_IRDL_TO_CPP_TARGET "${MLIR_IRDL_TO_CPP_TARGET}" CACHE INTERNAL "") From 0da3cb64da051f6e70d1dd4a55a3b9c3596e0b04 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Wed, 29 Jan 2025 15:00:21 +0000 Subject: [PATCH 22/94] build driver --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 13 +++++++----- .../Target/IRDLToCpp/Templates/DialectDef.txt | 21 +++++++++++++++++++ .../lib/Target/IRDLToCpp/Templates/Driver.txt | 15 +++++++++++++ .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 3 +++ .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 9 +++++++- 5 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/Driver.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 8a0deeaf4e408..12a15547bdf8d 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -279,11 +279,6 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, output << "#ifdef " << definitionMacroFlag << "\n#undef " << definitionMacroFlag << "\n"; - output << llvm::formatv(dialectDefTemplateText, dialectStrings.namespaceOpen, - dialectStrings.namespaceClose, - dialectStrings.dialectCppName, - dialectStrings.namespacePath); - // type header output << llvm::formatv( typeHeaderDefTemplateText, dialectStrings.dialectBaseTypeName, @@ -432,6 +427,14 @@ static void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &od output << llvm::formatv(opDefTemplateText, commaSeparatedOpList, perOpDefinitions); + output << llvm::formatv(dialectDefTemplateText, dialectStrings.namespaceOpen, + dialectStrings.namespaceClose, + dialectStrings.dialectCppName, + dialectStrings.namespacePath, + commaSeparatedOpList, + commaSeparatedTypeList + ); + output << "#endif // " << definitionMacroFlag << "\n"; return success(); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt index ce8724e0c39a0..93301667871d5 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt @@ -1,3 +1,14 @@ +/* +{0}: namespace open +{1}: namespace close + +{2}: Dialect Cpp Name +{3}: Namespace path + +{4}: Op list +{5}: Type list +*/ + R"( MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) {0} @@ -8,5 +19,15 @@ MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) } {2}::~{2}() = default; + + +void {2}::initialize() {{ + addOperations< + {4} + >(); + addTypes< + {5} + >(); +} {1} )" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt b/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt new file mode 100644 index 0000000000000..01852285ac638 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt @@ -0,0 +1,15 @@ +/* +{0}: Dialect CppName + +{1}: Namespace path + +{2}: Includes +*/ + +R"( + + + + + +)" \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index e69de29bb2d1d..57d24812e928d 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -0,0 +1,3 @@ + +#include "test_irdl_to_cpp.irdl.mlir.cpp.inc" + diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index 48caa8c89ce6f..f765f9315177c 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -1 +1,8 @@ -irdl.dialect @test_irdl_to_cpp {} +irdl.dialect @test_irdl_to_cpp { + irdl.type @foo + + irdl.operation @bar { + %0 = irdl.any + irdl.results(res: %0) + } +} From dfdb06adbd84a0536d0be4ea81ab45573a2f2b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= <30992420+Moxinilian@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:27:50 +0100 Subject: [PATCH 23/94] first step towards IRDL to cpp test (#18) --- mlir/lib/Target/IRDLToCpp/CMakeLists.txt | 11 +++++++++++ .../Target/IRDLToCpp/Templates/DialectDef.txt | 2 +- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 17 +++++++++++++++++ .../TestIRDLToCpp/TestIRDLToCppDialect.h | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h diff --git a/mlir/lib/Target/IRDLToCpp/CMakeLists.txt b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt index b66687fc8b044..e39fff8c804be 100644 --- a/mlir/lib/Target/IRDLToCpp/CMakeLists.txt +++ b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt @@ -2,6 +2,17 @@ add_mlir_translation_library(MLIRTargetIRDLToCpp TranslationRegistration.cpp IRDLToCpp.cpp + Templates/DialectDecl.txt + Templates/DialectDef.txt + Templates/Header.txt + Templates/OperationDef.txt + Templates/PerOperationDecl.txt + Templates/PerOperationDef.txt + Templates/TypeDecl.txt + Templates/TypeDef.txt + Templates/TypeHeaderDecl.txt + Templates/TypeHeaderDef.txt + LINK_LIBS PUBLIC MLIRIR MLIRIRDL diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt index 93301667871d5..979ac845a965d 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt @@ -10,7 +10,6 @@ */ R"( -MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) {0} {2}::{2}(::mlir::MLIRContext *context) : ::mlir::Dialect(getDialectNamespace(), context, ::mlir::TypeID::get<{2}>()) @@ -30,4 +29,5 @@ void {2}::initialize() {{ >(); } {1} +MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) )" diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 57d24812e928d..71e29130124c7 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -1,3 +1,20 @@ +//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file includes TestIRDLToCpp dialect. +// +//===----------------------------------------------------------------------===// +#include "mlir/IR/Dialect.h" +#include "mlir/IR/Region.h" + +#include "TestIRDLToCppDialect.h" + +#define GEN_DIALECT_DEF #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h new file mode 100644 index 0000000000000..0b99657e9d9c8 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h @@ -0,0 +1,19 @@ +//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file includes TestIRDLToCpp dialect headers. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H +#define MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H + +#define GEN_DIALECT_DECL_HEADER +#include "test_irdl_to_cpp.irdl.mlir.cpp.inc" + +#endif // MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H From 19ae518df15be8b10b031897690a0e8f26eb350c Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Feb 2025 10:22:05 +0000 Subject: [PATCH 24/94] header builds --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 4 ++-- mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt | 12 ++++++------ .../Target/IRDLToCpp/Templates/PerOperationDecl.txt | 6 +++--- .../Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp | 13 +++++++++---- .../Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 12a15547bdf8d..cead10e336787 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -193,7 +193,7 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto operandCount = opStrings.opOperandNames.size(); const auto operandNames = - operandCount ? stringify(opStrings.opOperandNames) : "{}"; + operandCount ? stringify(opStrings.opOperandNames) : "{\"\"}"; const auto resultCount = opStrings.opResultNames.size(); const auto resultNames = stringify(opStrings.opResultNames); @@ -376,7 +376,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, const auto operandCount = opStrings.opOperandNames.size(); const auto operandNames = - operandCount ? stringify(opStrings.opOperandNames) : "{}"; + operandCount ? stringify(opStrings.opOperandNames) : "{\"\"}"; const auto resultCount = opStrings.opResultNames.size(); const auto resultNames = stringify(opStrings.opResultNames); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt index 763a738ddb680..825cfa2e780b1 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt @@ -12,13 +12,13 @@ public: return ::llvm::StringLiteral("{4}"); } - /// Parse an attribute registered to this dialect. - ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser, - ::mlir::Type type) const override; + // /// Parse an attribute registered to this dialect. + // ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser, + // ::mlir::Type type) const override; - /// Print an attribute registered to this dialect. - void printAttribute(::mlir::Attribute attr, - ::mlir::DialectAsmPrinter &os) const override; + // /// Print an attribute registered to this dialect. + // void printAttribute(::mlir::Attribute attr, + // ::mlir::DialectAsmPrinter &os) const override; /// Parse a type registered to this dialect. ::mlir::Type parseType(::mlir::DialectAsmParser &parser) const override; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 5c9f048f9904d..b612c0dff40e4 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -142,9 +142,9 @@ public: std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } - ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() {{ - return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); - } + // ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() {{ + // return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); + // } {7} static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 71e29130124c7..c52465ee16666 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -10,11 +10,16 @@ // //===----------------------------------------------------------------------===// -#include "mlir/IR/Dialect.h" +// #include "mlir/IR/Dialect.h" #include "mlir/IR/Region.h" -#include "TestIRDLToCppDialect.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/Interfaces/InferTypeOpInterface.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/TypeSwitch.h" -#define GEN_DIALECT_DEF -#include "test_irdl_to_cpp.irdl.mlir.cpp.inc" +#include "TestIRDLToCppDialect.h" +// #define GEN_DIALECT_DEF +// #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" +// #undef GEN_DIALECT_DEF \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h index 0b99657e9d9c8..af15fda92ed93 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h @@ -15,5 +15,6 @@ #define GEN_DIALECT_DECL_HEADER #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" +#undef GEN_DIALECT_DECL_HEADER #endif // MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H From 9160c954b275dfe398d5433f68c0c91848ca0433 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Feb 2025 10:47:26 +0000 Subject: [PATCH 25/94] fixed compile errors in define --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 11 +++-------- .../Target/IRDLToCpp/Templates/PerOperationDef.txt | 6 +++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index cead10e336787..42c1436e7e9ee 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -121,11 +121,6 @@ static OpStrings getStrings(irdl::OperationOp op) { return names; }; - const auto operandCount = operandOp ? operandOp->getNumOperands() : 0; - - const auto resultCount = resultsOp.getNumOperands(); - const auto resultAttrArray = getNames(resultsOp); - OpStrings strings; strings.opName = op.getSymName(); strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); @@ -383,7 +378,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, const auto buildDefinition = llvm::formatv( R"( -static void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ +void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ {3} {4} } @@ -405,13 +400,13 @@ static void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &od opStrings.opOperandNames, [](StringRef attr) -> std::string { return llvm::formatv( - " odsBuilder.addOperands({0});", attr); + " odsState.addOperands({0});", attr); }), "\n"), llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef attr) -> std::string { return llvm::formatv( - " odsBuilder.addTypes({0});", + " odsState.addTypes({0});", attr); }), "\n")); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index 953b62c928d63..19ad07462c20a 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -39,9 +39,9 @@ R"( void {1}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ assert(operands.size() == {3}); assert(resultTypes.size() == {5}); - odsBuilder.addOperands(operands); - odsBuilder.addAttributes(attributes); - odsBuilder.addTypes(resultTypes); + odsState.addOperands(operands); + odsState.addAttributes(attributes); + odsState.addTypes(resultTypes); } From 2c496ece9b4f395f6ebc877575588c34aa9fcb37 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Feb 2025 16:07:42 +0000 Subject: [PATCH 26/94] successful registration in mlir-opt --- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 20 ++++++++++++++++--- .../lib/Dialect/TestIRDLToCpp/test.test.mlir | 5 +++++ mlir/tools/mlir-opt/CMakeLists.txt | 1 + mlir/tools/mlir-opt/mlir-opt.cpp | 2 ++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index c52465ee16666..11178f13cb378 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -15,11 +15,25 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/Interfaces/InferTypeOpInterface.h" +#include "mlir/IR/DialectImplementation.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/TypeSwitch.h" +#include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" +#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" +#include "mlir/Target/LLVMIR/LLVMTranslationInterface.h" +#include "mlir/Target/LLVMIR/ModuleTranslation.h" +#include "mlir/Tools/mlir-translate/Translation.h" + #include "TestIRDLToCppDialect.h" -// #define GEN_DIALECT_DEF -// #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" -// #undef GEN_DIALECT_DEF \ No newline at end of file +#define GEN_DIALECT_DEF +#define GET_TYPEDEF_CLASSES +#define GET_OP_CLASSES +#include "test_irdl_to_cpp.irdl.mlir.cpp.inc" + +namespace test { +void registerIrdlTestDialect(mlir::DialectRegistry& registry) { + registry.insert(); +} +} diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir new file mode 100644 index 0000000000000..29c2447b1f786 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir @@ -0,0 +1,5 @@ +func.func @test() { + %1 = arith.constant 5 : i32 + test_irdl_to_cpp.bar() : () -> i32 + return +} \ No newline at end of file diff --git a/mlir/tools/mlir-opt/CMakeLists.txt b/mlir/tools/mlir-opt/CMakeLists.txt index 3563d66fa9e79..bc85c95252adc 100644 --- a/mlir/tools/mlir-opt/CMakeLists.txt +++ b/mlir/tools/mlir-opt/CMakeLists.txt @@ -53,6 +53,7 @@ if(MLIR_INCLUDE_TESTS) set(test_libs ${test_libs} MLIRTestPDLL MLIRTestTransformDialect + MLIRTestIRDLToCppDialect ) if (MLIR_ENABLE_PDL_IN_PATTERNMATCH) diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 960f7037a1b61..2e905521a0fbe 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -168,6 +168,7 @@ void registerTestDialect(DialectRegistry &); void registerTestDynDialect(DialectRegistry &); void registerTestTilingInterfaceTransformDialectExtension(DialectRegistry &); void registerTestTransformDialectExtension(DialectRegistry &); +void registerIrdlTestDialect(DialectRegistry&); } // namespace test #ifdef MLIR_INCLUDE_TESTS @@ -321,6 +322,7 @@ int main(int argc, char **argv) { ::test::registerTestTransformDialectExtension(registry); ::test::registerTestTilingInterfaceTransformDialectExtension(registry); ::test::registerTestDynDialect(registry); + ::test::registerIrdlTestDialect(registry); #endif return mlir::asMainReturnCode(mlir::MlirOptMain( argc, argv, "MLIR modular optimizer driver\n", registry)); From b3801fec32b03b9cea4cb817b51b17d3257073c2 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 4 Feb 2025 23:08:44 +0000 Subject: [PATCH 27/94] abort fix --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 11 +---- .../IRDLToCpp/Templates/PerOperationDef.txt | 44 +++++++++---------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 42c1436e7e9ee..1093ec33c47ea 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -115,12 +115,6 @@ static OpStrings getStrings(irdl::OperationOp op) { auto resultsOp = *block.getOps().begin(); - constexpr auto getNames = [](auto op) { - auto names = llvm::map_range( - op.getNames(), [](auto &attr) { return mlir::cast(attr); }); - return names; - }; - OpStrings strings; strings.opName = op.getSymName(); strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); @@ -411,9 +405,8 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, }), "\n")); return llvm::formatv( - perOpDefTemplateText, opStrings.opName, opStrings.opCppName, - dialectStrings.dialectName, operandCount, operandNames, - resultCount, resultNames, buildDefinition, + perOpDefTemplateText, opStrings.opCppName, operandCount, + resultCount, buildDefinition, dialectStrings.namespaceOpen, dialectStrings.namespaceClose, dialectStrings.namespacePath); }), diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index 19ad07462c20a..a742952b1a5c0 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -1,44 +1,40 @@ /* -0: Operation Name -1: Operation CppName -2: Dialect Name -3: Operand count -4: Operand names -5: Result count -6: Result names -7: Build definitions - -8: open namespace -9: close namespace -10: namespace path +0: Operation CppName +1: Operand count +2: Result count +3: Build definitions + +4: open namespace +5: close namespace +6: namespace path */ R"( //===----------------------------------------------------------------------===// -// {10}::{1} definitions +// {6}::{0} definitions //===----------------------------------------------------------------------===// -{8} +{4} -::llvm::LogicalResult {1}::verifyInvariantsImpl() {{ +::llvm::LogicalResult {0}::verifyInvariantsImpl() {{ return ::mlir::success(); } -::llvm::LogicalResult {1}::verifyInvariants() {{ +::llvm::LogicalResult {0}::verifyInvariants() {{ return verifyInvariantsImpl(); } -::mlir::ParseResult {1}::parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result) {{ +::mlir::ParseResult {0}::parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result) {{ assert(false && "not implemented"); return ::mlir::failure(); } -{7} +{3} -void {1}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ - assert(operands.size() == {3}); - assert(resultTypes.size() == {5}); +void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ + assert(operands.size() == {1}); + assert(resultTypes.size() == {2}); odsState.addOperands(operands); odsState.addAttributes(attributes); odsState.addTypes(resultTypes); @@ -46,11 +42,11 @@ void {1}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, -void {1}::print(::mlir::OpAsmPrinter &_odsPrinter) {{ +void {0}::print(::mlir::OpAsmPrinter &_odsPrinter) {{ assert(false && "not implemented"); } -{9} +{5} -MLIR_DEFINE_EXPLICIT_TYPE_ID({10}::{1}) +MLIR_DEFINE_EXPLICIT_TYPE_ID({6}::{0}) )" \ No newline at end of file From 3b9a32d259a72b4f5490e794f348766e8838e90b Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Thu, 6 Feb 2025 10:01:03 +0000 Subject: [PATCH 28/94] removed custom print and parse --- .../Target/IRDLToCpp/Templates/PerOperationDecl.txt | 2 -- .../lib/Target/IRDLToCpp/Templates/PerOperationDef.txt | 10 ---------- mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir | 2 +- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index b612c0dff40e4..dc46db131f85a 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -151,8 +151,6 @@ public: ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); - static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); - void print(::mlir::OpAsmPrinter &_odsPrinter); public: }; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index a742952b1a5c0..c9f7c3c7d8a17 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -25,11 +25,6 @@ R"( return verifyInvariantsImpl(); } -::mlir::ParseResult {0}::parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result) {{ - assert(false && "not implemented"); - return ::mlir::failure(); -} - {3} void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ @@ -41,11 +36,6 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, } - -void {0}::print(::mlir::OpAsmPrinter &_odsPrinter) {{ - assert(false && "not implemented"); -} - {5} MLIR_DEFINE_EXPLICIT_TYPE_ID({6}::{0}) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir index 29c2447b1f786..c8381d7d925ee 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir @@ -1,5 +1,5 @@ func.func @test() { %1 = arith.constant 5 : i32 - test_irdl_to_cpp.bar() : () -> i32 + "test_irdl_to_cpp.bar"() : () -> i32 return } \ No newline at end of file From 35d9dba81ae556e29e392cf2272f08bd4f89ce3a Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Thu, 6 Feb 2025 10:47:34 +0000 Subject: [PATCH 29/94] simplified test case --- mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir index c8381d7d925ee..7044edf0bec20 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir @@ -1,5 +1,3 @@ -func.func @test() { - %1 = arith.constant 5 : i32 - "test_irdl_to_cpp.bar"() : () -> i32 - return +module { + %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } \ No newline at end of file From 1cbb39da42df631074b37f59c9361075b9719edc Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Mon, 10 Feb 2025 22:39:09 +0000 Subject: [PATCH 30/94] [IRDL2CPP] Attempt at Templating (#19) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * escape and replace characters in string * templater * more sensible parsing * maybe i'm out of my mind (#20) * ported some templates to templater * migrated definitions * migrated all templates * preserve loaded templates, moved stringify definition * renamed stringify to join --------- Co-authored-by: Théo Degioanni <30992420+Moxinilian@users.noreply.github.com> --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 260 +++++++++--------- .../IRDLToCpp/Templates/DialectDecl.txt | 15 +- .../Target/IRDLToCpp/Templates/DialectDef.txt | 33 +-- .../IRDLToCpp/Templates/OperationDef.txt | 4 +- .../IRDLToCpp/Templates/PerOperationDecl.txt | 82 +++--- .../IRDLToCpp/Templates/PerOperationDef.txt | 20 +- .../IRDLToCpp/Templates/TemplatingUtils.h | 74 +++++ .../Target/IRDLToCpp/Templates/TypeDecl.txt | 14 +- .../Target/IRDLToCpp/Templates/TypeDef.txt | 20 +- .../IRDLToCpp/Templates/TypeDefTest.cpp | 31 +++ .../IRDLToCpp/Templates/TypeHeaderDecl.txt | 8 +- .../IRDLToCpp/Templates/TypeHeaderDef.txt | 8 +- 12 files changed, 333 insertions(+), 236 deletions(-) create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h create mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 1093ec33c47ea..0fe9fa336311f 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -15,58 +15,17 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" +#include "Templates/TemplatingUtils.h" + using namespace mlir; constexpr char headerTemplateText[] = #include "Templates/Header.txt" ; -// 0: Namespace open -// 1: Namespace close -// 2: Dialect C++ name -// 3: Dialect namespace -// 4: Dialect name -constexpr char dialectDeclTemplateText[] = -#include "Templates/DialectDecl.txt" - ; - -// 0: Namespace open -// 1: Namespace close -// 2: Dialect C++ name -// 3: Dialect namespace -constexpr char dialectDefTemplateText[] = -#include "Templates/DialectDef.txt" - ; - constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; -constexpr char typeHeaderDeclTemplateText[] = -#include "Templates/TypeHeaderDecl.txt" - ; - -constexpr char typeHeaderDefTemplateText[] = -#include "Templates/TypeHeaderDef.txt" - ; - -constexpr char typeDeclTemplateText[] = -#include "Templates/TypeDecl.txt" - ; - -constexpr char typeDefTemplateText[] = -#include "Templates/TypeDef.txt" - ; -constexpr char perOpDeclTemplateText[] = -#include "Templates/PerOperationDecl.txt" - ; - -constexpr char perOpDefTemplateText[] = -#include "Templates/PerOperationDef.txt" - ; - -constexpr char opDefTemplateText[] = -#include "Templates/OperationDef.txt" - ; namespace { @@ -98,6 +57,14 @@ static std::string capitalize(StringRef str) { str.slice(1, str.size())); } +static std::string joinNameList(llvm::ArrayRef names) { + std::string nameArray; + llvm::raw_string_ostream nameArrayStream(nameArray); + nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; + + return nameArray; +} + static TypeStrings getStrings(irdl::TypeOp type) { TypeStrings strings; strings.typeName = type.getSymName(); @@ -131,6 +98,36 @@ static OpStrings getStrings(irdl::OperationOp op) { return strings; } +static void fillDict(irdl::detail::dictionary& dict, const TypeStrings& strings) { + dict["TYPE_NAME"] = strings.typeName; + dict["TYPE_CPP_NAME"] = strings.typeCppName; +} + +static void fillDict(irdl::detail::dictionary& dict, const OpStrings& strings) { + + const auto operandCount = strings.opOperandNames.size(); + const auto resultCount = strings.opResultNames.size(); + + dict["OP_NAME"] = strings.opName; + dict["OP_CPP_NAME"] = strings.opCppName; + dict["OP_OPERAND_COUNT"] = std::to_string(strings.opOperandNames.size()); + dict["OP_RESULT_COUNT"] = std::to_string(strings.opResultNames.size()); + dict["OP_OPERAND_INITIALIZER_LIST"] = operandCount ? joinNameList(strings.opOperandNames) : "{\"\"}"; + dict["OP_RESULT_INITIALIZER_LIST"] = resultCount ? joinNameList(strings.opResultNames) : "{\"\"}"; + +} + + +static void fillDict(irdl::detail::dictionary& dict, const DialectStrings& strings) { + dict["DIALECT_NAME"] = strings.dialectName; + dict["DIALECT_BASE_TYPE_NAME"] = strings.dialectBaseTypeName; + dict["DIALECT_CPP_NAME"] = strings.dialectCppName; + dict["DIALECT_CPP_SHORT_NAME"] = strings.dialectCppShortName; + dict["NAMESPACE_OPEN"] = strings.namespaceOpen; + dict["NAMESPACE_CLOSE"] = strings.namespaceClose; + dict["NAMESPACE_PATH"] = strings.namespacePath; +} + static LogicalResult generateTypedefList(mlir::Block &dialectBlock, llvm::SmallVector &typeNames) { @@ -153,41 +150,32 @@ static LogicalResult generateOpList(mlir::Block &dialectBlock, } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, - DialectStrings &dialectStrings) { + irdl::detail::dictionary &dict) { + + static const auto typeDeclTemplate = irdl::detail::Template( + #include "Templates/TypeDecl.txt" + ); const auto typeStrings = getStrings(type); + fillDict(dict, typeStrings); - output << llvm::formatv( - typeDeclTemplateText, typeStrings.typeName, typeStrings.typeCppName, - dialectStrings.dialectName, dialectStrings.dialectBaseTypeName, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose, - dialectStrings.namespacePath); + typeDeclTemplate.render(output, dict); return success(); } static LogicalResult generateOperationInclude(irdl::OperationOp op, raw_ostream &output, - DialectStrings &dialectStrings) { - + irdl::detail::dictionary &dict) { + static const auto perOpDeclTemplate = irdl::detail::Template( + #include "Templates/PerOperationDecl.txt" + ); const auto opStrings = getStrings(op); + fillDict(dict, opStrings); - constexpr auto stringify = [](auto &&names) -> std::string { - std::string nameArray; - llvm::raw_string_ostream nameArrayStream(nameArray); - nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; - - return nameArray; - }; - - const auto operandCount = opStrings.opOperandNames.size(); - const auto operandNames = - operandCount ? stringify(opStrings.opOperandNames) : "{\"\"}"; - - const auto resultCount = opStrings.opResultNames.size(); - const auto resultNames = stringify(opStrings.opResultNames); - - const auto buildDeclaration = llvm::formatv( + std::string tmp; + llvm::raw_string_ostream stream {tmp}; + stream << llvm::formatv( R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef name) -> std::string { @@ -201,38 +189,37 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, name); }), "")); + dict["OP_BUILD_DECLS"] = tmp; - output << llvm::formatv( - perOpDeclTemplateText, opStrings.opName, opStrings.opCppName, - dialectStrings.dialectName, operandCount, operandNames, resultCount, - resultNames, buildDeclaration, dialectStrings.namespaceOpen, - dialectStrings.namespaceClose, dialectStrings.namespacePath); - + perOpDeclTemplate.render(output, dict); return success(); } static LogicalResult generateInclude(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { + static const auto dialectDeclTemplate = irdl::detail::Template( + #include "Templates/DialectDecl.txt" + ); + static const auto typeHeaderDeclTemplate = irdl::detail::Template( + #include "Templates/TypeHeaderDecl.txt" + ); + output << "#ifdef " << declarationMacroFlag << "\n#undef " << declarationMacroFlag << "\n"; - output << llvm::formatv( - dialectDeclTemplateText, dialectStrings.namespaceOpen, - dialectStrings.namespaceClose, dialectStrings.dialectCppName, - dialectStrings.namespacePath, dialectStrings.dialectName); + irdl::detail::dictionary dict; + fillDict(dict, dialectStrings); - output << llvm::formatv( - typeHeaderDeclTemplateText, dialectStrings.dialectBaseTypeName, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose, - dialectStrings.namespacePath); + dialectDeclTemplate.render(output, dict); + typeHeaderDeclTemplate.render(output, dict); auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); auto typeOps = dialectBlock.getOps(); auto operationOps = dialectBlock.getOps(); for (auto &&typeOp : typeOps) { - if (failed(generateTypeInclude(typeOp, output, dialectStrings))) + if (failed(generateTypeInclude(typeOp, output, dict))) return failure(); } @@ -254,7 +241,7 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, output << forwardDeclarations; for (auto &&operationOp : operationOps) { - if (failed(generateOperationInclude(operationOp, output, dialectStrings))) + if (failed(generateOperationInclude(operationOp, output, dict))) return failure(); } @@ -265,14 +252,30 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { + + static const auto typeHeaderDefTemplate = mlir::irdl::detail::Template{ + #include "Templates/TypeHeaderDef.txt" + }; + static const auto opDefTemplate = mlir::irdl::detail::Template{ + #include "Templates/OperationDef.txt" + }; + static const auto typeDefTemplate = mlir::irdl::detail::Template{ + #include "Templates/TypeDef.txt" + }; + static const auto dialectDefTemplate = mlir::irdl::detail::Template{ + #include "Templates/DialectDef.txt" + }; + static const auto perOpDefTemplate = mlir::irdl::detail::Template { + #include "Templates/PerOperationDef.txt" + }; + + irdl::detail::dictionary dict; + fillDict(dict, dialectStrings); + output << "#ifdef " << definitionMacroFlag << "\n#undef " << definitionMacroFlag << "\n"; - // type header - output << llvm::formatv( - typeHeaderDefTemplateText, dialectStrings.dialectBaseTypeName, - dialectStrings.dialectCppName, dialectStrings.namespaceOpen, - dialectStrings.namespaceClose); + typeHeaderDefTemplate.render(output, dict); // get typedef list auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); @@ -280,7 +283,8 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, if (failed(generateTypedefList(dialectBlock, typeNames))) return failure(); - const auto commaSeparatedTypeList = llvm::join( + + dict["TYPE_LIST"] = llvm::join( llvm::map_range(typeNames, [&dialectStrings](llvm::StringRef name) -> std::string { return llvm::formatv( @@ -288,7 +292,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), ",\n"); - const auto generatedTypeParser = llvm::formatv( + dict["TYPE_PARSER"] =llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser) {0} @@ -310,7 +314,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), "\n")); - const auto generatedTypePrinter = llvm::formatv( + dict["TYPE_PRINTER"] = llvm::formatv( R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) { return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def) {0} @@ -327,20 +331,22 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), "\n")); - const auto typeIdDefinitions = llvm::join(llvm::map_range(typeNames, [&](StringRef name) -> std::string { - return llvm::formatv("MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", name, dialectStrings.namespacePath); - }), "\n"); + dict["TYPE_DEFINES"] = llvm::join(llvm::map_range(typeNames, + [&](StringRef name) -> std::string { + return llvm::formatv( + "MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", + name, dialectStrings.namespacePath); + }), + "\n"); - output << llvm::formatv( - typeDefTemplateText, commaSeparatedTypeList, generatedTypeParser, - generatedTypePrinter, dialectStrings.dialectCppName, typeIdDefinitions, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose); + typeDefTemplate.render(output, dict); // get op list auto operations = dialectBlock.getOps(); llvm::SmallVector opNames; if (failed(generateOpList(dialectBlock, opNames))) return failure(); + const auto commaSeparatedOpList = llvm::join( llvm::map_range(opNames, [&dialectStrings](llvm::StringRef name) -> std::string { @@ -352,23 +358,15 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, const auto perOpDefinitions = llvm::join( llvm::map_range( operations, - [&dialectStrings](irdl::OperationOp op) -> std::string { + [&dict, &perOpDefTemplate = perOpDefTemplate](irdl::OperationOp op) -> std::string { auto opStrings = getStrings(op); - - constexpr auto stringify = [](auto &&names) -> std::string { - std::string nameArray; - llvm::raw_string_ostream nameArrayStream(nameArray); - nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}"; - - return nameArray; - }; + fillDict(dict, opStrings); const auto operandCount = opStrings.opOperandNames.size(); const auto operandNames = - operandCount ? stringify(opStrings.opOperandNames) : "{\"\"}"; + operandCount ? joinNameList(opStrings.opOperandNames) : "{\"\"}"; - const auto resultCount = opStrings.opResultNames.size(); - const auto resultNames = stringify(opStrings.opResultNames); + const auto resultNames = joinNameList(opStrings.opResultNames); const auto buildDefinition = llvm::formatv( R"( @@ -390,12 +388,12 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, "::mlir::Value {0}, ", attr); }), ""), - llvm::join(llvm::map_range( - opStrings.opOperandNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - " odsState.addOperands({0});", attr); - }), + llvm::join(llvm::map_range(opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " odsState.addOperands({0});", + attr); + }), "\n"), llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef attr) -> std::string { @@ -404,24 +402,19 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, attr); }), "\n")); - return llvm::formatv( - perOpDefTemplateText, opStrings.opCppName, operandCount, - resultCount, buildDefinition, - dialectStrings.namespaceOpen, dialectStrings.namespaceClose, - dialectStrings.namespacePath); + dict["OP_BUILD_DEFS"] = buildDefinition; + + std::string str; + llvm::raw_string_ostream stream{str}; + perOpDefTemplate.render(stream, dict); + return str; }), "\n"); - output << llvm::formatv(opDefTemplateText, commaSeparatedOpList, - perOpDefinitions); - - output << llvm::formatv(dialectDefTemplateText, dialectStrings.namespaceOpen, - dialectStrings.namespaceClose, - dialectStrings.dialectCppName, - dialectStrings.namespacePath, - commaSeparatedOpList, - commaSeparatedTypeList - ); + dict["OP_LIST"] = commaSeparatedOpList; + dict["OP_CLASSES"] = perOpDefinitions; + opDefTemplate.render(output, dict); + dialectDefTemplate.render(output, dict); output << "#endif // " << definitionMacroFlag << "\n"; return success(); @@ -429,6 +422,10 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { + static const auto typeDefTempl = detail::Template( +#include "Templates/TypeDefTest.cpp" + ); + StringRef dialectName = dialect.getSymName(); // TODO: deal with no more constraints than the verifier allows. @@ -474,6 +471,7 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, output << headerTemplateText; + if (failed(generateInclude(dialect, output, dialectStrings))) return failure(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt index 825cfa2e780b1..2b919e3380502 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt @@ -1,15 +1,16 @@ R"( -{0} -class {2} : public ::mlir::Dialect { - explicit {2}(::mlir::MLIRContext *context); +__NAMESPACE_OPEN__ + +class __DIALECT_CPP_NAME__ : public ::mlir::Dialect { + explicit __DIALECT_CPP_NAME__(::mlir::MLIRContext *context); void initialize(); friend class ::mlir::MLIRContext; public: - ~{2}() override; + ~__DIALECT_CPP_NAME__() override; static constexpr ::llvm::StringLiteral getDialectNamespace() { - return ::llvm::StringLiteral("{4}"); + return ::llvm::StringLiteral("__DIALECT_NAME__"); } // /// Parse an attribute registered to this dialect. @@ -28,8 +29,8 @@ public: ::mlir::DialectAsmPrinter &os) const override; }; -{1} +__NAMESPACE_CLOSE__ -MLIR_DECLARE_EXPLICIT_TYPE_ID({3}::{2}) +MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__DIALECT_CPP_NAME__) )" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt index 979ac845a965d..ec55c644116f6 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt @@ -1,33 +1,26 @@ -/* -{0}: namespace open -{1}: namespace close - -{2}: Dialect Cpp Name -{3}: Namespace path +R"( -{4}: Op list -{5}: Type list -*/ +__NAMESPACE_OPEN__ -R"( -{0} -{2}::{2}(::mlir::MLIRContext *context) - : ::mlir::Dialect(getDialectNamespace(), context, ::mlir::TypeID::get<{2}>()) -{{ +__DIALECT_CPP_NAME__::__DIALECT_CPP_NAME__(::mlir::MLIRContext *context) + : ::mlir::Dialect(getDialectNamespace(), context, ::mlir::TypeID::get<__DIALECT_CPP_NAME__>()) +{ initialize(); } -{2}::~{2}() = default; +__DIALECT_CPP_NAME__::~__DIALECT_CPP_NAME__() = default; -void {2}::initialize() {{ +void __DIALECT_CPP_NAME__::initialize() { addOperations< - {4} + __OP_LIST__ >(); addTypes< - {5} + __TYPE_LIST__ >(); } -{1} -MLIR_DEFINE_EXPLICIT_TYPE_ID({3}::{2}) + +__NAMESPACE_CLOSE__ + +MLIR_DEFINE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__DIALECT_CPP_NAME__) )" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt index ba795083ac45e..e4192b47cae87 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt @@ -7,7 +7,7 @@ R"( #ifdef GET_OP_LIST #undef GET_OP_LIST -{0} +__OP_LIST__ #endif // GET_OP_LIST @@ -15,7 +15,7 @@ R"( #ifdef GET_OP_CLASSES #undef GET_OP_CLASSES -{1} +__OP_CLASSES__ #endif // GET_OP_CLASSES )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index dc46db131f85a..6e0ad661ac686 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -14,24 +14,24 @@ */ R"( -{8} +__NAMESPACE_OPEN__ namespace detail { -class {1}GenericAdaptorBase { +class __OP_CPP_NAME__GenericAdaptorBase { public: protected: ::mlir::DictionaryAttr odsAttrs; ::std::optional<::mlir::OperationName> odsOpName; ::mlir::RegionRange odsRegions; public: - {1}GenericAdaptorBase(::mlir::DictionaryAttr attrs = {{}, const ::mlir::EmptyProperties &properties = {{}, ::mlir::RegionRange regions = {{}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) - odsOpName.emplace("{2}.{0}", odsAttrs.getContext()); + __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) + odsOpName.emplace("__DIALECT_NAME__.__OP_NAME__", odsAttrs.getContext()); } - {1}GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {{} + __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); - ::mlir::DictionaryAttr getAttributes() {{ + ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } @@ -39,34 +39,34 @@ public: } // namespace detail template -class {1}GenericAdaptor : public detail::{1}GenericAdaptorBase { +class __OP_CPP_NAME__GenericAdaptor : public detail::__OP_CPP_NAME__GenericAdaptorBase { using ValueT = ::llvm::detail::ValueOfRange; - using Base = detail::{1}GenericAdaptorBase; + using Base = detail::__OP_CPP_NAME__GenericAdaptorBase; public: - {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {{}, const ::mlir::EmptyProperties &properties = {{}, ::mlir::RegionRange regions = {{}) : Base(attrs, properties, regions), odsOperands(values) {{} + __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} - {1}GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {{}) : {1}GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{{}), regions) {{} + __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {}) : __OP_CPP_NAME__GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{}), regions) {} - {1}GenericAdaptor(RangeT values, const {1}GenericAdaptorBase &base) : Base(base), odsOperands(values) {{} + __OP_CPP_NAME__GenericAdaptor(RangeT values, const __OP_CPP_NAME__GenericAdaptorBase &base) : Base(base), odsOperands(values) {} - template >> - {1}GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {{} + template >> + __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} - std::pair getODSOperandIndexAndLength(unsigned index) {{ + std::pair getODSOperandIndexAndLength(unsigned index) { return Base::getODSOperandIndexAndLength(index, odsOperands.size()); } RangeT getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); - return {{std::next(odsOperands.begin(), valueRange.first), + return {std::next(odsOperands.begin(), valueRange.first), std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } - RangeT getArgs() {{ + RangeT getArgs() { return getODSOperands(0); } - RangeT getOperands() {{ + RangeT getOperands() { return odsOperands; } @@ -74,80 +74,80 @@ private: RangeT odsOperands; }; -class {1}Adaptor : public {1}GenericAdaptor<::mlir::ValueRange> { +class __OP_CPP_NAME__Adaptor : public __OP_CPP_NAME__GenericAdaptor<::mlir::ValueRange> { public: - using {1}GenericAdaptor::{1}GenericAdaptor; - {1}Adaptor({1} op); + using __OP_CPP_NAME__GenericAdaptor::__OP_CPP_NAME__GenericAdaptor; + __OP_CPP_NAME__Adaptor(__OP_CPP_NAME__ op); ::llvm::LogicalResult verify(::mlir::Location loc); }; -class {1} : public ::mlir::Op<{1}> { +class __OP_CPP_NAME__ : public ::mlir::Op<__OP_CPP_NAME__> { public: using Op::Op; using Op::print; - using Adaptor = {1}Adaptor; + using Adaptor = __OP_CPP_NAME__Adaptor; template - using GenericAdaptor = {1}GenericAdaptor; + using GenericAdaptor = __OP_CPP_NAME__GenericAdaptor; using FoldAdaptor = GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute>>; static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { - return {{}; + return {}; } static constexpr ::llvm::StringLiteral getOperationName() { - return ::llvm::StringLiteral("{2}.{0}"); + return ::llvm::StringLiteral("__DIALECT_NAME__.__OP_NAME__"); } static ::llvm::ArrayRef<::llvm::StringRef> getOperandNames() { - static ::llvm::StringRef operandNames[] = {4}; + static ::llvm::StringRef operandNames[] = __OP_OPERAND_INITIALIZER_LIST__; return operandNames; } - static ::llvm::StringRef getOperandName(unsigned index) {{ - assert(index < {3} && "invalid attribute index"); + static ::llvm::StringRef getOperandName(unsigned index) { + assert(index < __OP_OPERAND_COUNT__ && "invalid attribute index"); return getOperandNames()[index]; } static ::llvm::ArrayRef<::llvm::StringRef> getResultNames() { - static ::llvm::StringRef resultNames[] = {6}; + static ::llvm::StringRef resultNames[] = __OP_RESULT_INITIALIZER_LIST__; return resultNames; } - static ::llvm::StringRef getResultName(unsigned index) {{ - assert(index < {5} && "invalid attribute index"); + static ::llvm::StringRef getResultName(unsigned index) { + assert(index < __OP_RESULT_COUNT__ && "invalid attribute index"); return getResultNames()[index]; } std::pair getODSOperandIndexAndLength(unsigned index) { - return {index, {3}}; + return {index, __OP_OPERAND_COUNT__}; } ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); - return {{std::next(getOperation()->operand_begin(), valueRange.first), + return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } - ::mlir::Operation::operand_range getArgs() {{ + ::mlir::Operation::operand_range getArgs() { return getODSOperands(0); } ::mlir::MutableOperandRange getArgsMutable(); std::pair getODSResultIndexAndLength(unsigned index) { - return {{index, {5}}; + return {index, __OP_RESULT_COUNT__}; } ::mlir::Operation::result_range getODSResults(unsigned index) { auto valueRange = getODSResultIndexAndLength(index); - return {{std::next(getOperation()->result_begin(), valueRange.first), + return {std::next(getOperation()->result_begin(), valueRange.first), std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } - // ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() {{ + // ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() { // return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); // } - {7} - static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{}); + __OP_BUILD_DECLS__ + static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); @@ -155,8 +155,8 @@ public: }; -{9} +__NAMESPACE_CLOSE__ -MLIR_DECLARE_EXPLICIT_TYPE_ID({10}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__OP_CPP_NAME__) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index c9f7c3c7d8a17..32a114e053d46 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -12,31 +12,31 @@ R"( //===----------------------------------------------------------------------===// -// {6}::{0} definitions +// __NAMESPACE_PATH__::__OP_CPP_NAME__ definitions //===----------------------------------------------------------------------===// -{4} +__NAMESPACE_OPEN__ -::llvm::LogicalResult {0}::verifyInvariantsImpl() {{ +::llvm::LogicalResult __OP_CPP_NAME__::verifyInvariantsImpl() { return ::mlir::success(); } -::llvm::LogicalResult {0}::verifyInvariants() {{ +::llvm::LogicalResult __OP_CPP_NAME__::verifyInvariants() { return verifyInvariantsImpl(); } -{3} +__OP_BUILD_DEFS__ -void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ - assert(operands.size() == {1}); - assert(resultTypes.size() == {2}); +void __OP_CPP_NAME__::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) { + assert(operands.size() == __OP_OPERAND_COUNT__); + assert(resultTypes.size() == __OP_RESULT_COUNT__); odsState.addOperands(operands); odsState.addAttributes(attributes); odsState.addTypes(resultTypes); } -{5} +__NAMESPACE_CLOSE__ -MLIR_DEFINE_EXPLICIT_TYPE_ID({6}::{0}) +MLIR_DEFINE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__OP_CPP_NAME__) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h b/mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h new file mode 100644 index 0000000000000..a1b948e77a5ca --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h @@ -0,0 +1,74 @@ +#ifndef IRDLTOCPP_TEMPLATE_UTILS_H +#define IRDLTOCPP_TEMPLATE_UTILS_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include + +namespace mlir::irdl::detail { + +using dictionary = llvm::StringMap>; + +class Template { +public: + Template(llvm::StringRef str) { + bool processingReplacementToken = false; + while (!str.empty()) { + auto [token, remainder] = str.split("__"); + + if (processingReplacementToken) { + assert(!token.empty() && "replacement name cannot be empty"); + bytecode.emplace_back(ReplacementToken{token}); + } else { + if (!token.empty()) + bytecode.emplace_back(LiteralToken{token}); + } + + processingReplacementToken = !processingReplacementToken; + str = remainder; + } + } + + void render(llvm::raw_ostream &out, const dictionary &replacements) const { + for (auto instruction : bytecode) { + std::visit( + [&](auto &&inst) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + out << inst.text; + } else if constexpr (std::is_same_v) { + auto replacement = replacements.find(inst.keyName); +#ifndef NDEBUG + if (replacement == replacements.end()) { + llvm::errs() + << "Missing template key: " << inst.keyName << "\n"; + llvm_unreachable("Missing template key"); + } +#endif + out << replacement->second; + } else { + static_assert(false, "non-exhaustive visitor!"); + } + }, + instruction); + } + } + +private: + struct LiteralToken { + llvm::StringRef text; + }; + + struct ReplacementToken { + llvm::StringRef keyName; + }; + + std::vector> bytecode; +}; + +} // namespace mlir::irdl::detail + +#endif // #ifndef IRDLTOCPP_TEMPLATE_UTILS_H diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index 66c503cdc33db..d5c2e7e6bdb43 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -11,19 +11,19 @@ R"( -{4} +__NAMESPACE_OPEN__ -class {1} : public ::mlir::Type::TypeBase<{1}, {3}, ::mlir::TypeStorage> { +class __TYPE_CPP_NAME__ : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, __DIALECT_BASE_TYPE_NAME__, ::mlir::TypeStorage> { public: using Base::Base; - static constexpr ::llvm::StringLiteral name = "{2}.{0}"; - static constexpr ::llvm::StringLiteral dialectName = "{2}"; + static constexpr ::llvm::StringLiteral name = "__DIALECT_NAME__.__TYPE_NAME__"; + static constexpr ::llvm::StringLiteral dialectName = "__DIALECT_NAME__"; static constexpr ::llvm::StringLiteral getMnemonic() { - return {"{0}"}; + return {"__TYPE_NAME__"}; } }; -{5} +__NAMESPACE_CLOSE__ -MLIR_DECLARE_EXPLICIT_TYPE_ID({6}::{1}) +MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__TYPE_CPP_NAME__) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index 3f8afff2fbe25..1e770dd0935dd 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -12,7 +12,7 @@ R"( #ifdef GET_TYPEDEF_LIST #undef GET_TYPEDEF_LIST -{0} +__TYPE_LIST__ #endif // GET_TYPEDEF_LIST @@ -20,16 +20,16 @@ R"( #ifdef GET_TYPEDEF_CLASSES #undef GET_TYPEDEF_CLASSES -{4} +__TYPE_DEFINES__ -{5} +__NAMESPACE_OPEN__ -{1} +__TYPE_PARSER__ -{2} +__TYPE_PRINTER__ /// Parse a type registered to this dialect. -::mlir::Type {3}::parseType(::mlir::DialectAsmParser &parser) const {{ +::mlir::Type __DIALECT_CPP_NAME__::parseType(::mlir::DialectAsmParser &parser) const { ::llvm::SMLoc typeLoc = parser.getCurrentLocation(); ::llvm::StringRef mnemonic; ::mlir::Type genType; @@ -39,16 +39,16 @@ R"( parser.emitError(typeLoc) << "unknown type `" << mnemonic << "` in dialect `" << getNamespace() << "`"; - return {{}; + return {}; } /// Print a type registered to this dialect. -void {3}::printType(::mlir::Type type, - ::mlir::DialectAsmPrinter &printer) const {{ +void __DIALECT_CPP_NAME__::printType(::mlir::Type type, + ::mlir::DialectAsmPrinter &printer) const { if (::mlir::succeeded(generatedTypePrinter(type, printer))) return; } -{6} +__NAMESPACE_CLOSE__ #endif // GET_TYPEDEF_CLASSES )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp b/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp new file mode 100644 index 0000000000000..8e74bb0bf8639 --- /dev/null +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp @@ -0,0 +1,31 @@ +/* +{0}: TypeDef list +{1}: TypeParser function +{2}: TypePrinter function +{3}: Dialect CppName +{4}: TypeID Defines +{5}: Namespace open +{6}: Namespace close +*/ + +R"( + +__NAMESPACE_OPEN__ + +class __TYPE_CPP_NAME__ : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, __DIALECT_CPP_NAME__, ::mlir::TypeStorage> { +public: + using Base::Base; + static constexpr ::llvm::StringLiteral name = "__DIALECT_NAME__.__TYPE_NAME__"; + static constexpr ::llvm::StringLiteral dialectName = "__DIALECT_NAME__"; + static constexpr ::llvm::StringLiteral getMnemonic() { + return {"__TYPE_NAME__"}; + } +}; + +__NAMESPACE_CLOSE__ + +MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__TYPE_CPP_NAME__) + + +)" + diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index 0093b07e5b91e..e4e2ead7abe22 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -8,16 +8,16 @@ R"( -{1} +__NAMESPACE_OPEN__ -class {0} : public ::mlir::Type {{ +class __DIALECT_BASE_TYPE_NAME__ : public ::mlir::Type { public: using Type::Type; static bool classof(Type type); }; -{2} +__NAMESPACE_CLOSE__ -MLIR_DECLARE_EXPLICIT_TYPE_ID({3}::{0}) +MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__DIALECT_BASE_TYPE_NAME__) )" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt index 7889c5f737419..c3e341fff2085 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt @@ -7,11 +7,11 @@ */ R"( -{2} +__NAMESPACE_OPEN__ -bool {0}::classof(Type type) {{ - return llvm::isa<{1}>(type.getDialect()); +bool __DIALECT_BASE_TYPE_NAME__::classof(Type type) { + return llvm::isa<__DIALECT_CPP_NAME__>(type.getDialect()); } -{3} +__NAMESPACE_CLOSE__ )" From aac4b985ca6eacde05e6196002534d5f3705a762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Sat, 1 Mar 2025 00:20:17 +0100 Subject: [PATCH 31/94] some changes --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 111 +++++++++--------- .../lib/Target/IRDLToCpp/Templates/Driver.txt | 15 --- .../IRDLToCpp/Templates/PerOperationDecl.txt | 28 +---- .../Target/IRDLToCpp/Templates/TypeDecl.txt | 13 +- .../IRDLToCpp/Templates/TypeDefTest.cpp | 31 ----- .../{Templates => }/TemplatingUtils.h | 8 ++ 6 files changed, 71 insertions(+), 135 deletions(-) delete mode 100644 mlir/lib/Target/IRDLToCpp/Templates/Driver.txt delete mode 100644 mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp rename mlir/lib/Target/IRDLToCpp/{Templates => }/TemplatingUtils.h (84%) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 0fe9fa336311f..8f1eaee5cdf81 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "mlir/Target/IRDLToCpp/IRDLToCpp.h" +#include "mlir/Dialect/IRDL/IR/IRDL.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -15,7 +16,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" -#include "Templates/TemplatingUtils.h" +#include "TemplatingUtils.h" using namespace mlir; @@ -26,7 +27,6 @@ constexpr char headerTemplateText[] = constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER"; constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; - namespace { struct DialectStrings { @@ -73,38 +73,42 @@ static TypeStrings getStrings(irdl::TypeOp type) { } static OpStrings getStrings(irdl::OperationOp op) { - - auto &block = op.getBody().getBlocks().front(); - - auto operands = block.getOps(); + auto operands = op.getOps(); auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); - auto resultsOp = *block.getOps().begin(); + auto results = op.getOps(); + auto resultOp = + results.empty() ? std::optional{} : *results.begin(); OpStrings strings; strings.opName = op.getSymName(); strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); - if (operandOp) + + if (operandOp) { strings.opOperandNames = llvm::SmallVector( llvm::map_range(operandOp->getNames(), [](Attribute attr) { return llvm::formatv("{0}", cast(attr)); })); - strings.opResultNames = llvm::SmallVector( - llvm::map_range(resultsOp.getNames(), [](Attribute attr) { - return llvm::formatv("{0}", cast(attr)); - })); + } + + if (resultOp) { + strings.opResultNames = llvm::SmallVector( + llvm::map_range(resultOp->getNames(), [](Attribute attr) { + return llvm::formatv("{0}", cast(attr)); + })); + } return strings; } -static void fillDict(irdl::detail::dictionary& dict, const TypeStrings& strings) { +static void fillDict(irdl::detail::dictionary &dict, + const TypeStrings &strings) { dict["TYPE_NAME"] = strings.typeName; dict["TYPE_CPP_NAME"] = strings.typeCppName; } -static void fillDict(irdl::detail::dictionary& dict, const OpStrings& strings) { - +static void fillDict(irdl::detail::dictionary &dict, const OpStrings &strings) { const auto operandCount = strings.opOperandNames.size(); const auto resultCount = strings.opResultNames.size(); @@ -112,13 +116,14 @@ static void fillDict(irdl::detail::dictionary& dict, const OpStrings& strings) { dict["OP_CPP_NAME"] = strings.opCppName; dict["OP_OPERAND_COUNT"] = std::to_string(strings.opOperandNames.size()); dict["OP_RESULT_COUNT"] = std::to_string(strings.opResultNames.size()); - dict["OP_OPERAND_INITIALIZER_LIST"] = operandCount ? joinNameList(strings.opOperandNames) : "{\"\"}"; - dict["OP_RESULT_INITIALIZER_LIST"] = resultCount ? joinNameList(strings.opResultNames) : "{\"\"}"; - + dict["OP_OPERAND_INITIALIZER_LIST"] = + operandCount ? joinNameList(strings.opOperandNames) : "{\"\"}"; + dict["OP_RESULT_INITIALIZER_LIST"] = + resultCount ? joinNameList(strings.opResultNames) : "{\"\"}"; } - -static void fillDict(irdl::detail::dictionary& dict, const DialectStrings& strings) { +static void fillDict(irdl::detail::dictionary &dict, + const DialectStrings &strings) { dict["DIALECT_NAME"] = strings.dialectName; dict["DIALECT_BASE_TYPE_NAME"] = strings.dialectBaseTypeName; dict["DIALECT_CPP_NAME"] = strings.dialectCppName; @@ -128,32 +133,28 @@ static void fillDict(irdl::detail::dictionary& dict, const DialectStrings& strin dict["NAMESPACE_PATH"] = strings.namespacePath; } -static LogicalResult -generateTypedefList(mlir::Block &dialectBlock, - llvm::SmallVector &typeNames) { - auto typeOps = dialectBlock.getOps(); +static void generateTypedefList(irdl::DialectOp &dialect, + llvm::SmallVector &typeNames) { + auto typeOps = dialect.getOps(); auto range = llvm::map_range( typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); typeNames = llvm::SmallVector(range); - return success(); } -static LogicalResult generateOpList(mlir::Block &dialectBlock, - llvm::SmallVector &typeNames) { - auto typeOps = dialectBlock.getOps(); +static void generateOpList(irdl::DialectOp &dialect, + llvm::SmallVector &opNames) { + auto operationOps = dialect.getOps(); auto range = llvm::map_range( - typeOps, [](auto &&type) { return getStrings(type).opCppName; }); - typeNames = llvm::SmallVector(range); - return success(); + operationOps, [](auto &&op) { return getStrings(op).opCppName; }); + opNames = llvm::SmallVector(range); } } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, irdl::detail::dictionary &dict) { - static const auto typeDeclTemplate = irdl::detail::Template( - #include "Templates/TypeDecl.txt" +#include "Templates/TypeDecl.txt" ); const auto typeStrings = getStrings(type); @@ -168,13 +169,13 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, raw_ostream &output, irdl::detail::dictionary &dict) { static const auto perOpDeclTemplate = irdl::detail::Template( - #include "Templates/PerOperationDecl.txt" - ); +#include "Templates/PerOperationDecl.txt" + ); const auto opStrings = getStrings(op); fillDict(dict, opStrings); std::string tmp; - llvm::raw_string_ostream stream {tmp}; + llvm::raw_string_ostream stream{tmp}; stream << llvm::formatv( R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", llvm::join(llvm::map_range(opStrings.opResultNames, @@ -199,12 +200,12 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { static const auto dialectDeclTemplate = irdl::detail::Template( - #include "Templates/DialectDecl.txt" +#include "Templates/DialectDecl.txt" ); static const auto typeHeaderDeclTemplate = irdl::detail::Template( - #include "Templates/TypeHeaderDecl.txt" +#include "Templates/TypeHeaderDecl.txt" ); - + output << "#ifdef " << declarationMacroFlag << "\n#undef " << declarationMacroFlag << "\n"; @@ -254,19 +255,19 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { static const auto typeHeaderDefTemplate = mlir::irdl::detail::Template{ - #include "Templates/TypeHeaderDef.txt" +#include "Templates/TypeHeaderDef.txt" }; static const auto opDefTemplate = mlir::irdl::detail::Template{ - #include "Templates/OperationDef.txt" +#include "Templates/OperationDef.txt" }; static const auto typeDefTemplate = mlir::irdl::detail::Template{ - #include "Templates/TypeDef.txt" +#include "Templates/TypeDef.txt" }; static const auto dialectDefTemplate = mlir::irdl::detail::Template{ - #include "Templates/DialectDef.txt" +#include "Templates/DialectDef.txt" }; - static const auto perOpDefTemplate = mlir::irdl::detail::Template { - #include "Templates/PerOperationDef.txt" + static const auto perOpDefTemplate = mlir::irdl::detail::Template{ +#include "Templates/PerOperationDef.txt" }; irdl::detail::dictionary dict; @@ -278,12 +279,10 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, typeHeaderDefTemplate.render(output, dict); // get typedef list - auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); llvm::SmallVector typeNames; - if (failed(generateTypedefList(dialectBlock, typeNames))) + if (failed(generateTypedefList(dialect, typeNames))) return failure(); - dict["TYPE_LIST"] = llvm::join( llvm::map_range(typeNames, [&dialectStrings](llvm::StringRef name) -> std::string { @@ -292,7 +291,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), ",\n"); - dict["TYPE_PARSER"] =llvm::formatv( + dict["TYPE_PARSER"] = llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser) {0} @@ -331,7 +330,8 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), "\n")); - dict["TYPE_DEFINES"] = llvm::join(llvm::map_range(typeNames, + dict["TYPE_DEFINES"] = + llvm::join(llvm::map_range(typeNames, [&](StringRef name) -> std::string { return llvm::formatv( "MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", @@ -346,7 +346,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, llvm::SmallVector opNames; if (failed(generateOpList(dialectBlock, opNames))) return failure(); - + const auto commaSeparatedOpList = llvm::join( llvm::map_range(opNames, [&dialectStrings](llvm::StringRef name) -> std::string { @@ -358,13 +358,15 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, const auto perOpDefinitions = llvm::join( llvm::map_range( operations, - [&dict, &perOpDefTemplate = perOpDefTemplate](irdl::OperationOp op) -> std::string { + [&dict, &perOpDefTemplate = + perOpDefTemplate](irdl::OperationOp op) -> std::string { auto opStrings = getStrings(op); fillDict(dict, opStrings); const auto operandCount = opStrings.opOperandNames.size(); const auto operandNames = - operandCount ? joinNameList(opStrings.opOperandNames) : "{\"\"}"; + operandCount ? joinNameList(opStrings.opOperandNames) + : "{\"\"}"; const auto resultNames = joinNameList(opStrings.opResultNames); @@ -413,7 +415,7 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, dict["OP_LIST"] = commaSeparatedOpList; dict["OP_CLASSES"] = perOpDefinitions; - opDefTemplate.render(output, dict); + opDefTemplate.render(output, dict); dialectDefTemplate.render(output, dict); output << "#endif // " << definitionMacroFlag << "\n"; @@ -471,7 +473,6 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, output << headerTemplateText; - if (failed(generateInclude(dialect, output, dialectStrings))) return failure(); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt b/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt deleted file mode 100644 index 01852285ac638..0000000000000 --- a/mlir/lib/Target/IRDLToCpp/Templates/Driver.txt +++ /dev/null @@ -1,15 +0,0 @@ -/* -{0}: Dialect CppName - -{1}: Namespace path - -{2}: Includes -*/ - -R"( - - - - - -)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 6e0ad661ac686..22a13c4887a2f 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -1,22 +1,8 @@ -/* -0: Operation Name -1: Operation CppName -2: Dialect Name -3: Operand count -4: Operand names -5: Result count -6: Result names -7: Build declarations - -8: open namespace -9: close namespace -10: namespace path -*/ - R"( __NAMESPACE_OPEN__ namespace detail { + class __OP_CPP_NAME__GenericAdaptorBase { public: protected: @@ -24,18 +10,20 @@ protected: ::std::optional<::mlir::OperationName> odsOpName; ::mlir::RegionRange odsRegions; public: - __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) + __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { + if (odsAttrs) odsOpName.emplace("__DIALECT_NAME__.__OP_NAME__", odsAttrs.getContext()); } __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); + ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } - }; + } // namespace detail template @@ -142,10 +130,6 @@ public: std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } - // ::mlir::TypedValue<::mlir::irdl::AttributeType> getOutput() { - // return ::llvm::cast<::mlir::TypedValue<::mlir::irdl::AttributeType>>(*getODSResults(0).begin()); - // } - __OP_BUILD_DECLS__ static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); @@ -159,4 +143,4 @@ __NAMESPACE_CLOSE__ MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__OP_CPP_NAME__) -)" \ No newline at end of file +)" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index d5c2e7e6bdb43..a34259f904d03 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -1,14 +1,3 @@ -/* -{0}: Type Name -{1}: Type CppName -{2}: Dialect Name -{3}: Dialect BaseTypeName - -{4}: Namespace open -{5}: Namespace close -{6}: Namespace path -*/ - R"( __NAMESPACE_OPEN__ @@ -26,4 +15,4 @@ public: __NAMESPACE_CLOSE__ MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__TYPE_CPP_NAME__) -)" \ No newline at end of file +)" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp b/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp deleted file mode 100644 index 8e74bb0bf8639..0000000000000 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDefTest.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -{0}: TypeDef list -{1}: TypeParser function -{2}: TypePrinter function -{3}: Dialect CppName -{4}: TypeID Defines -{5}: Namespace open -{6}: Namespace close -*/ - -R"( - -__NAMESPACE_OPEN__ - -class __TYPE_CPP_NAME__ : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, __DIALECT_CPP_NAME__, ::mlir::TypeStorage> { -public: - using Base::Base; - static constexpr ::llvm::StringLiteral name = "__DIALECT_NAME__.__TYPE_NAME__"; - static constexpr ::llvm::StringLiteral dialectName = "__DIALECT_NAME__"; - static constexpr ::llvm::StringLiteral getMnemonic() { - return {"__TYPE_NAME__"}; - } -}; - -__NAMESPACE_CLOSE__ - -MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__TYPE_CPP_NAME__) - - -)" - diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h similarity index 84% rename from mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h rename to mlir/lib/Target/IRDLToCpp/TemplatingUtils.h index a1b948e77a5ca..1c46a5550f7c4 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TemplatingUtils.h +++ b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h @@ -1,3 +1,11 @@ +//===- TemplatingUtils.h - Templater for text templates -----------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + #ifndef IRDLTOCPP_TEMPLATE_UTILS_H #define IRDLTOCPP_TEMPLATE_UTILS_H From 5f77c3a316cdb55372379137b3a142ffaa41c7bb Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Sat, 1 Mar 2025 19:40:55 +0000 Subject: [PATCH 32/94] fixed errors --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 8f1eaee5cdf81..55fc095fef9a1 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -133,20 +133,22 @@ static void fillDict(irdl::detail::dictionary &dict, dict["NAMESPACE_PATH"] = strings.namespacePath; } -static void generateTypedefList(irdl::DialectOp &dialect, - llvm::SmallVector &typeNames) { +static LogicalResult generateTypedefList(irdl::DialectOp &dialect, + llvm::SmallVector& typeNames) { auto typeOps = dialect.getOps(); auto range = llvm::map_range( typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); typeNames = llvm::SmallVector(range); + return success(); } -static void generateOpList(irdl::DialectOp &dialect, - llvm::SmallVector &opNames) { +static LogicalResult generateOpList(irdl::DialectOp &dialect, + llvm::SmallVector& opNames) { auto operationOps = dialect.getOps(); auto range = llvm::map_range( operationOps, [](auto &&op) { return getStrings(op).opCppName; }); opNames = llvm::SmallVector(range); + return success(); } } // namespace @@ -225,7 +227,7 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, } llvm::SmallVector opNames; - if (failed(generateOpList(dialectBlock, opNames))) + if (failed(generateOpList(dialect, opNames))) return failure(); const auto forwardDeclarations = llvm::formatv( R"( @@ -342,9 +344,10 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, typeDefTemplate.render(output, dict); // get op list + auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); auto operations = dialectBlock.getOps(); llvm::SmallVector opNames; - if (failed(generateOpList(dialectBlock, opNames))) + if (failed(generateOpList(dialect, opNames))) return failure(); const auto commaSeparatedOpList = llvm::join( @@ -425,7 +428,7 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { static const auto typeDefTempl = detail::Template( -#include "Templates/TypeDefTest.cpp" +#include "Templates/TypeDef.txt" ); StringRef dialectName = dialect.getSymName(); From f00bf0dc9c401997efb8b0db75ccc777e03e5c42 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 13:18:07 +0000 Subject: [PATCH 33/94] getters for operands --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 12 +++++++++++- .../Target/IRDLToCpp/Templates/PerOperationDecl.txt | 10 ++++++++++ .../Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 7 +++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 55fc095fef9a1..a201b5b5e9e5c 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -176,6 +176,17 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto opStrings = getStrings(op); fillDict(dict, opStrings); + auto getters = std::string{}; + + for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { + const auto& op = opStrings.opOperandNames[i]; + getters += llvm::formatv( + "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n " + , capitalize(op), i + ); + } + + dict["OP_GETTER_DECLS"] = getters; std::string tmp; llvm::raw_string_ostream stream{tmp}; stream << llvm::formatv( @@ -207,7 +218,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, static const auto typeHeaderDeclTemplate = irdl::detail::Template( #include "Templates/TypeHeaderDecl.txt" ); - output << "#ifdef " << declarationMacroFlag << "\n#undef " << declarationMacroFlag << "\n"; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 22a13c4887a2f..14992e3417216 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -5,9 +5,12 @@ namespace detail { class __OP_CPP_NAME__GenericAdaptorBase { public: + struct Properties { + }; protected: ::mlir::DictionaryAttr odsAttrs; ::std::optional<::mlir::OperationName> odsOpName; + Properties properties; ::mlir::RegionRange odsRegions; public: __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { @@ -19,6 +22,9 @@ public: std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); + const Properties &getProperties() { + return properties; + } ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } @@ -58,6 +64,8 @@ public: return odsOperands; } + __OP_GETTER_DECLS__ + private: RangeT odsOperands; }; @@ -131,6 +139,8 @@ public: } __OP_BUILD_DECLS__ + + __OP_GETTER_DECLS__ static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); ::llvm::LogicalResult verifyInvariantsImpl(); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index f765f9315177c..6fde670213db8 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -5,4 +5,11 @@ irdl.dialect @test_irdl_to_cpp { %0 = irdl.any irdl.results(res: %0) } + + + irdl.operation @beef { + %0 = irdl.any + irdl.operands(lhs: %0, rhs: %0) + irdl.results(res: %0) + } } From 739e8b1f8cca3a7a7f270718d9f0c71b7d615398 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 13:19:41 +0000 Subject: [PATCH 34/94] clang-format --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index a201b5b5e9e5c..c87fbf7367074 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -133,8 +133,9 @@ static void fillDict(irdl::detail::dictionary &dict, dict["NAMESPACE_PATH"] = strings.namespacePath; } -static LogicalResult generateTypedefList(irdl::DialectOp &dialect, - llvm::SmallVector& typeNames) { +static LogicalResult +generateTypedefList(irdl::DialectOp &dialect, + llvm::SmallVector &typeNames) { auto typeOps = dialect.getOps(); auto range = llvm::map_range( typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); @@ -143,7 +144,7 @@ static LogicalResult generateTypedefList(irdl::DialectOp &dialect, } static LogicalResult generateOpList(irdl::DialectOp &dialect, - llvm::SmallVector& opNames) { + llvm::SmallVector &opNames) { auto operationOps = dialect.getOps(); auto range = llvm::map_range( operationOps, [](auto &&op) { return getStrings(op).opCppName; }); @@ -176,16 +177,15 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto opStrings = getStrings(op); fillDict(dict, opStrings); - auto getters = std::string{}; + auto getters = std::string{}; for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { - const auto& op = opStrings.opOperandNames[i]; - getters += llvm::formatv( - "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n " - , capitalize(op), i - ); + const auto &op = opStrings.opOperandNames[i]; + getters += llvm::formatv( + "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n ", + capitalize(op), i); } - + dict["OP_GETTER_DECLS"] = getters; std::string tmp; llvm::raw_string_ostream stream{tmp}; From 9736b13fa3c9912f85f5dd6749dedc4f992bd1a2 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 13:25:00 +0000 Subject: [PATCH 35/94] removed unneeded functions --- .../IRDLToCpp/Templates/PerOperationDecl.txt | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 14992e3417216..625e3015de7f5 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -56,10 +56,6 @@ public: std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } - RangeT getArgs() { - return getODSOperands(0); - } - RangeT getOperands() { return odsOperands; } @@ -123,24 +119,9 @@ public: std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } - ::mlir::Operation::operand_range getArgs() { - return getODSOperands(0); - } - - ::mlir::MutableOperandRange getArgsMutable(); - std::pair getODSResultIndexAndLength(unsigned index) { - return {index, __OP_RESULT_COUNT__}; - } - - ::mlir::Operation::result_range getODSResults(unsigned index) { - auto valueRange = getODSResultIndexAndLength(index); - return {std::next(getOperation()->result_begin(), valueRange.first), - std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; - } - - __OP_BUILD_DECLS__ - __OP_GETTER_DECLS__ + + __OP_BUILD_DECLS__ static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); ::llvm::LogicalResult verifyInvariantsImpl(); From 7727f155ad8e71d61148540f699e79c30233a044 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 13:50:58 +0000 Subject: [PATCH 36/94] handle errors --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index c87fbf7367074..aa93f06be1043 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -152,6 +152,10 @@ static LogicalResult generateOpList(irdl::DialectOp &dialect, return success(); } +static Block &getDialectBlock(irdl::DialectOp dialect) { + return *dialect.getRegion().getBlocks().begin(); +} + } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, @@ -227,7 +231,7 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, dialectDeclTemplate.render(output, dict); typeHeaderDeclTemplate.render(output, dict); - auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); + auto &dialectBlock = getDialectBlock(dialect); auto typeOps = dialectBlock.getOps(); auto operationOps = dialectBlock.getOps(); @@ -354,7 +358,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, typeDefTemplate.render(output, dict); // get op list - auto &dialectBlock = *dialect.getRegion().getBlocks().begin(); + auto &dialectBlock = getDialectBlock(dialect); auto operations = dialectBlock.getOps(); llvm::SmallVector opNames; if (failed(generateOpList(dialect, opNames))) @@ -435,6 +439,18 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, return success(); } +static LogicalResult verify(irdl::DialectOp dialect) { + auto &dialectBlock = getDialectBlock(dialect); + for (auto op : dialectBlock.getOps()) { + for (auto operand : op->getOperands()) { + if (!llvm::isa(operand.getDefiningOp())) + return op.emitError( + "IRDL C++ translation only supports irdl.any constraint for types"); + } + } + return success(); +} + LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output) { static const auto typeDefTempl = detail::Template( @@ -453,6 +469,9 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, return dialect->emitError( "dialect name must only contain letters, numbers or underscores"); + if (failed(verify(dialect))) + return failure(); + // TODO: allow more complex path. llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; From bc41321eeb666db4123d12b2571a5bda0ba7cc8f Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 15:29:37 +0000 Subject: [PATCH 37/94] support negative --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 16 ++++---- .../Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir | 13 ------- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 29 ++++++++++---- .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 12 ++++++ .../test_irdl_to_cpp_invalid.irdl.mlir | 18 +++++++++ .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 38 ++++++++++++++++--- 6 files changed, 92 insertions(+), 34 deletions(-) delete mode 100644 mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index aa93f06be1043..f75a6772569d5 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -442,10 +442,14 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, static LogicalResult verify(irdl::DialectOp dialect) { auto &dialectBlock = getDialectBlock(dialect); for (auto op : dialectBlock.getOps()) { - for (auto operand : op->getOperands()) { - if (!llvm::isa(operand.getDefiningOp())) - return op.emitError( - "IRDL C++ translation only supports irdl.any constraint for types"); + for (auto operands : op.getOps()) { + for (auto operand : operands.getOperands()) { + if (!llvm::isa(operand.getDefiningOp())) { + return operands.emitError( + "IRDL C++ translation only supports irdl.any " + "constraint for types"); + } + } } } return success(); @@ -488,9 +492,7 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, } // TODO: allow control over C++ name. - std::string cppShortName = - llvm::formatv("{0}{1}", llvm::toUpper(dialectName[0]), - dialectName.slice(1, dialectName.size())); + std::string cppShortName = capitalize(dialectName); std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); diff --git a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir b/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir deleted file mode 100644 index 0bfdac52dde49..0000000000000 --- a/mlir/test/Dialect/IRDL/test-irdl2cpp-mvp.irdl.mlir +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: mlir-opt %s | mlir-opt | FileCheck %s - -module { - irdl.dialect @testd { - irdl.type @singleton - - irdl.operation @foo { - %0 = irdl.any - irdl.operands(in1: %0, in2: %0) - irdl.results(out1: %0) - } - } -} diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 11178f13cb378..39d2e47b7bc1e 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -1,4 +1,5 @@ -//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -*-===// +//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ +//-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,16 +15,16 @@ #include "mlir/IR/Region.h" #include "mlir/IR/BuiltinTypes.h" -#include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/IR/DialectImplementation.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/TypeSwitch.h" +#include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/LLVMTranslationInterface.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "mlir/Tools/mlir-translate/Translation.h" - +#include "mlir/Transforms/DialectConversion.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/TypeSwitch.h" #include "TestIRDLToCppDialect.h" @@ -33,7 +34,19 @@ #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" namespace test { -void registerIrdlTestDialect(mlir::DialectRegistry& registry) { - registry.insert(); -} +using namespace mlir; +struct CloneOpConversion + : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(mlir::test_irdl_to_cpp::BeefOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + return success(); + } +}; + +void registerIrdlTestDialect(mlir::DialectRegistry ®istry) { + registry.insert(); } +} // namespace test diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index 6fde670213db8..e854c249edba7 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -1,12 +1,24 @@ +// RUN: mlir-irdl-to-cpp %s +// CHECK-LABEL: irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { + // CHECK: irdl.type @foo irdl.type @foo + // CHECK: irdl.type @bar { + // CHECK: %[[v0:[^ ]*]] = irdl.any + // CHECK: irdl.results(res: %[[v0]]) + // CHECK: } irdl.operation @bar { %0 = irdl.any irdl.results(res: %0) } + // CHECK: irdl.type @ beef { + // CHECK: %[[v0:[^ ]*]] = irdl.any + // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) + // CHECK: irdl.results(res: %[[v0]]) + // CHECK: } irdl.operation @beef { %0 = irdl.any irdl.operands(lhs: %0, rhs: %0) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir new file mode 100644 index 0000000000000..ffc84589b89d8 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir @@ -0,0 +1,18 @@ +// RUN: mlir-irdl-to-cpp %s --verify-diagnostics +irdl.dialect @test_irdl_to_cpp { + irdl.operation @results_no_any_of { + %0 = irdl.any + %1 = irdl.any_of(%0, %0) + irdl.results(res: %1) + } + + irdl.operation @operands_no_any_of { + %0 = irdl.any + %1 = irdl.any_of(%0, %0) + // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + irdl.operands(test: %1) + irdl.results(res: %0) + } +} + +// ----- \ No newline at end of file diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 5e0ee6c161a41..1c31b31e8e938 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -37,6 +37,15 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), llvm::cl::init("-")); + bool verifyDiagnosticsFlag; + static llvm::cl::opt + verifyDiagnostics( + "verify-diagnostics", + llvm::cl::desc("Check that emitted diagnostics match " + "expected-* lines on the corresponding line"), + llvm::cl::location(verifyDiagnosticsFlag), llvm::cl::init(false)); + llvm::InitLLVM y(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "mlir-irdl-to-cpp"); @@ -63,6 +72,8 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { registry.insert(); MLIRContext ctx(registry); ctx.printOpOnDiagnostic(true); + if (verifyDiagnostics) + ctx.printOpOnDiagnostic(false); ParserConfig parseConfig(&ctx); OwningOpRef op = @@ -72,7 +83,25 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { auto moduleOp = llvm::cast(*op); - SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); + if (!verifyDiagnostics) { + SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); + + for (Operation &op : moduleOp.getOps()) { + auto dialectOp = llvm::dyn_cast(op); + if (!dialectOp) + continue; + + // TODO: accept multiple operations in translation to not generate headers + // multiple times. + if (failed(irdl::translateIRDLDialectToCpp(dialectOp, output->os()))) { + return failure(); + } + } + output->keep(); + return success(); + } + + SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &ctx); for (Operation &op : moduleOp.getOps()) { auto dialectOp = llvm::dyn_cast(op); @@ -81,12 +110,9 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { // TODO: accept multiple operations in translation to not generate headers // multiple times. - if (failed(irdl::translateIRDLDialectToCpp(dialectOp, output->os()))) - return failure(); + ((void)irdl::translateIRDLDialectToCpp(dialectOp, output->os())); } - - output->keep(); - return success(); + return sourceMgrHandler.verify(); } int main(int argc, char **argv) { From 24b9d783622b318dcda700977ddc84ea7cb293e5 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 3 Mar 2025 15:50:35 +0000 Subject: [PATCH 38/94] check results type --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 17 +++++++++++++++-- .../test_irdl_to_cpp_invalid.irdl.mlir | 5 +++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index f75a6772569d5..cc9691d2be26c 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -441,8 +441,9 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, static LogicalResult verify(irdl::DialectOp dialect) { auto &dialectBlock = getDialectBlock(dialect); - for (auto op : dialectBlock.getOps()) { - for (auto operands : op.getOps()) { + for (auto operation : dialectBlock.getOps()) { + + for (auto operands : operation.getOps()) { for (auto operand : operands.getOperands()) { if (!llvm::isa(operand.getDefiningOp())) { return operands.emitError( @@ -451,7 +452,19 @@ static LogicalResult verify(irdl::DialectOp dialect) { } } } + + for (auto results : operation.getOps()) { + for (auto operand : results.getOperands()) { + llvm::errs() << "HELP"; + if (!llvm::isa(operand.getDefiningOp())) { + return results.emitError( + "IRDL C++ translation only supports irdl.any " + "constraint for types"); + } + } + } } + return success(); } diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir index ffc84589b89d8..a9a0242c22303 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir @@ -3,9 +3,14 @@ irdl.dialect @test_irdl_to_cpp { irdl.operation @results_no_any_of { %0 = irdl.any %1 = irdl.any_of(%0, %0) + // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} irdl.results(res: %1) } +} +// ----- +// no support for split-buffer yet +irdl.dialect @test_irdl_to_cpp_2 { irdl.operation @operands_no_any_of { %0 = irdl.any %1 = irdl.any_of(%0, %0) From cb754ee48cf0f29c24ce2df5bf19ad844de3bbec Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 7 Mar 2025 15:30:36 +0000 Subject: [PATCH 39/94] mlir-opt verify test --- mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir index 7044edf0bec20..098ba9bca2ea7 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir @@ -1,3 +1,5 @@ +// RUN: mlir-opt %s module { + // CHECK-LABEL: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } \ No newline at end of file From c8e98d95427fe671f4c12b0790269d8ab365ac9d Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 11:24:29 +0000 Subject: [PATCH 40/94] fixed the easy changes --- llvm/lib/Support/FormatVariadic.cpp | 1 - mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 1 - mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp | 3 +-- mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir | 4 ++-- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Support/FormatVariadic.cpp b/llvm/lib/Support/FormatVariadic.cpp index 8eb30b8338f90..f3e8d0a7fe6f3 100644 --- a/llvm/lib/Support/FormatVariadic.cpp +++ b/llvm/lib/Support/FormatVariadic.cpp @@ -82,7 +82,6 @@ static std::optional parseReplacementItem(StringRef Spec) { } RepString = RepString.trim(); if (!RepString.empty()) { - llvm::errs() << "content is: " << RepString << "\n"; assert(0 && "Unexpected characters found in replacement string!"); return std::nullopt; } diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index cc9691d2be26c..83c51f29ce130 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -455,7 +455,6 @@ static LogicalResult verify(irdl::DialectOp dialect) { for (auto results : operation.getOps()) { for (auto operand : results.getOperands()) { - llvm::errs() << "HELP"; if (!llvm::isa(operand.getDefiningOp())) { return results.emitError( "IRDL C++ translation only supports irdl.any " diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 39d2e47b7bc1e..2a8ccff4a51ee 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -35,8 +35,7 @@ namespace test { using namespace mlir; -struct CloneOpConversion - : public OpConversionPattern { +struct TestOpConversion : public OpConversionPattern { using OpConversionPattern::OpConversionPattern; LogicalResult diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir index 098ba9bca2ea7..5e97e9d3de69a 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir @@ -1,5 +1,5 @@ -// RUN: mlir-opt %s +// RUN: mlir-opt %s | FileCheck %s module { - // CHECK-LABEL: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo + // CHECK: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } \ No newline at end of file From 73e8ff9212a5573b3c6130910e4cdf230dd5ab73 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 13:13:45 +0000 Subject: [PATCH 41/94] PR changes pt ii --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 140 ++++++++++-------- .../IRDLToCpp/Templates/DialectDecl.txt | 8 - .../IRDLToCpp/Templates/PerOperationDecl.txt | 10 +- 3 files changed, 81 insertions(+), 77 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 83c51f29ce130..b7d45bac8865c 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -65,6 +65,20 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } +static std::string snakeToPascal(llvm::StringRef in) { + std::string output{static_cast(toupper(in.front()))}; + output.reserve(in.size()); + for (size_t i = 1; i < in.size(); ++i) { + if (in[i] == '_' && i + 1 < in.size()) { + output += toupper(in[i + 1]); + ++i; + } else { + output += in[i]; + } + } + return output; +} + static TypeStrings getStrings(irdl::TypeOp type) { TypeStrings strings; strings.typeName = type.getSymName(); @@ -152,10 +166,6 @@ static LogicalResult generateOpList(irdl::DialectOp &dialect, return success(); } -static Block &getDialectBlock(irdl::DialectOp dialect) { - return *dialect.getRegion().getBlocks().begin(); -} - } // namespace static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, @@ -184,15 +194,15 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto getters = std::string{}; for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { - const auto &op = opStrings.opOperandNames[i]; + const auto &op = snakeToPascal(opStrings.opOperandNames[i]); getters += llvm::formatv( "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n ", - capitalize(op), i); + op, i); } dict["OP_GETTER_DECLS"] = getters; - std::string tmp; - llvm::raw_string_ostream stream{tmp}; + std::string buildDecls; + llvm::raw_string_ostream stream{buildDecls}; stream << llvm::formatv( R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", llvm::join(llvm::map_range(opStrings.opResultNames, @@ -207,7 +217,7 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, name); }), "")); - dict["OP_BUILD_DECLS"] = tmp; + dict["OP_BUILD_DECLS"] = buildDecls; perOpDeclTemplate.render(output, dict); return success(); @@ -231,9 +241,8 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, dialectDeclTemplate.render(output, dict); typeHeaderDeclTemplate.render(output, dict); - auto &dialectBlock = getDialectBlock(dialect); - auto typeOps = dialectBlock.getOps(); - auto operationOps = dialectBlock.getOps(); + auto typeOps = dialect.getOps(); + auto operationOps = dialect.getOps(); for (auto &&typeOp : typeOps) { if (failed(generateTypeInclude(typeOp, output, dict))) @@ -243,17 +252,15 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, llvm::SmallVector opNames; if (failed(generateOpList(dialect, opNames))) return failure(); - const auto forwardDeclarations = llvm::formatv( - R"( -{1} -{0} -{2} - )", + + auto classDeclarations = llvm::join(llvm::map_range(opNames, [](llvm::StringRef name) -> std::string { return llvm::formatv("class {0};", name); }), - "\n"), + "\n"); + const auto forwardDeclarations = llvm::formatv( + "{1}\n{0}\n{2}", std::move(classDeclarations), dialectStrings.namespaceOpen, dialectStrings.namespaceClose); output << forwardDeclarations; @@ -307,6 +314,19 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), ",\n"); + auto typeCase = llvm::join( + llvm::map_range( + typeNames, + [&](llvm::StringRef name) -> std::string { + return llvm::formatv( + R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { +value = {1}::{0}::get(parser.getContext()); +return ::mlir::success(!!value); +}))", + name, dialectStrings.namespacePath); + }), + "\n"); + dict["TYPE_PARSER"] = llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser) @@ -316,18 +336,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, return std::nullopt; }); })", - llvm::join( - llvm::map_range( - typeNames, - [&](llvm::StringRef name) -> std::string { - return llvm::formatv( - R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { - value = {1}::{0}::get(parser.getContext()); - return ::mlir::success(!!value); - }))", - name, dialectStrings.namespacePath); - }), - "\n")); + std::move(typeCase)); dict["TYPE_PRINTER"] = llvm::formatv( R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) { @@ -358,8 +367,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, typeDefTemplate.render(output, dict); // get op list - auto &dialectBlock = getDialectBlock(dialect); - auto operations = dialectBlock.getOps(); + auto operations = dialect.getOps(); llvm::SmallVector opNames; if (failed(generateOpList(dialect, opNames))) return failure(); @@ -387,40 +395,46 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, const auto resultNames = joinNameList(opStrings.opResultNames); - const auto buildDefinition = llvm::formatv( - R"( -void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ -{3} -{4} -} - )", - opStrings.opCppName, + auto resultTypes = llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef attr) -> std::string { return llvm::formatv( "::mlir::Type {0}, ", attr); }), - ""), + ""); + auto operandTypes = llvm::join(llvm::map_range(opStrings.opOperandNames, [](StringRef attr) -> std::string { return llvm::formatv( "::mlir::Value {0}, ", attr); }), - ""), - llvm::join(llvm::map_range(opStrings.opOperandNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - " odsState.addOperands({0});", - attr); - }), - "\n"), - llvm::join(llvm::map_range(opStrings.opResultNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - " odsState.addTypes({0});", - attr); - }), - "\n")); + ""); + auto odsOperandAdder = llvm::join( + llvm::map_range(opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " odsState.addOperands({0});", attr); + }), + "\n"); + auto odsResultAdder = llvm::join( + llvm::map_range(opStrings.opResultNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " odsState.addTypes({0});", attr); + }), + "\n"); + + const auto buildDefinition = llvm::formatv( + R"( +void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ +{3} +{4} +} + )", + opStrings.opCppName, std::move(resultTypes), + std::move(operandTypes), std::move(odsOperandAdder), + std::move(odsResultAdder)); + dict["OP_BUILD_DEFS"] = buildDefinition; std::string str; @@ -439,10 +453,9 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, return success(); } -static LogicalResult verify(irdl::DialectOp dialect) { - auto &dialectBlock = getDialectBlock(dialect); - for (auto operation : dialectBlock.getOps()) { - +static LogicalResult verifySymbol(irdl::DialectOp dialect) { + for (auto operation : dialect.getOps()) { + // scan operands of operation for (auto operands : operation.getOps()) { for (auto operand : operands.getOperands()) { if (!llvm::isa(operand.getDefiningOp())) { @@ -453,6 +466,7 @@ static LogicalResult verify(irdl::DialectOp dialect) { } } + // scan results of operation for (auto results : operation.getOps()) { for (auto operand : results.getOperands()) { if (!llvm::isa(operand.getDefiningOp())) { @@ -485,10 +499,9 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, return dialect->emitError( "dialect name must only contain letters, numbers or underscores"); - if (failed(verify(dialect))) + if (failed(verifySymbol(dialect))) return failure(); - // TODO: allow more complex path. llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; std::string namespaceOpen; @@ -503,7 +516,6 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, namespacePathStream << "::" << pathElement; } - // TODO: allow control over C++ name. std::string cppShortName = capitalize(dialectName); std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt index 2b919e3380502..e0f85feadd196 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDecl.txt @@ -13,14 +13,6 @@ public: return ::llvm::StringLiteral("__DIALECT_NAME__"); } - // /// Parse an attribute registered to this dialect. - // ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser, - // ::mlir::Type type) const override; - - // /// Print an attribute registered to this dialect. - // void printAttribute(::mlir::Attribute attr, - // ::mlir::DialectAsmPrinter &os) const override; - /// Parse a type registered to this dialect. ::mlir::Type parseType(::mlir::DialectAsmParser &parser) const override; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 625e3015de7f5..0f28e61aadb62 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -7,11 +7,6 @@ class __OP_CPP_NAME__GenericAdaptorBase { public: struct Properties { }; -protected: - ::mlir::DictionaryAttr odsAttrs; - ::std::optional<::mlir::OperationName> odsOpName; - Properties properties; - ::mlir::RegionRange odsRegions; public: __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { if (odsAttrs) @@ -28,6 +23,11 @@ public: ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } +protected: + ::mlir::DictionaryAttr odsAttrs; + ::std::optional<::mlir::OperationName> odsOpName; + Properties properties; + ::mlir::RegionRange odsRegions; }; } // namespace detail From 98efc6269be9a8f0e146f3fd5975c1b8ef333952 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 13:24:47 +0000 Subject: [PATCH 42/94] case conversion --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 65 ++++++++++++------- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 2 +- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index b7d45bac8865c..38470154f0ec7 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -52,11 +52,6 @@ struct OpStrings { llvm::SmallVector opOperandNames; }; -static std::string capitalize(StringRef str) { - return llvm::formatv("{0}{1}", llvm::toUpper(str[0]), - str.slice(1, str.size())); -} - static std::string joinNameList(llvm::ArrayRef names) { std::string nameArray; llvm::raw_string_ostream nameArrayStream(nameArray); @@ -65,6 +60,20 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } +static std::string snakeToCamel(llvm::StringRef in) { + std::string output{}; + output.reserve(in.size()); + for (size_t i = 0; i < in.size(); ++i) { + if (in[i] == '_' && i + 1 < in.size()) { + output += toupper(in[i + 1]); + ++i; + } else { + output += in[i]; + } + } + return output; +} + static std::string snakeToPascal(llvm::StringRef in) { std::string output{static_cast(toupper(in.front()))}; output.reserve(in.size()); @@ -79,10 +88,18 @@ static std::string snakeToPascal(llvm::StringRef in) { return output; } +static std::string typeToCppName(irdl::TypeOp type) { + return llvm::formatv("{0}Type", snakeToPascal(type.getSymName())); +} + +static std::string opToCppName(irdl::OperationOp op) { + return llvm::formatv("{0}Op", snakeToPascal(op.getSymName())); +} + static TypeStrings getStrings(irdl::TypeOp type) { TypeStrings strings; strings.typeName = type.getSymName(); - strings.typeCppName = llvm::formatv("{0}Type", capitalize(strings.typeName)); + strings.typeCppName = typeToCppName(type); return strings; } @@ -97,7 +114,7 @@ static OpStrings getStrings(irdl::OperationOp op) { OpStrings strings; strings.opName = op.getSymName(); - strings.opCppName = llvm::formatv("{0}Op", capitalize(strings.opName)); + strings.opCppName = opToCppName(op); if (operandOp) { strings.opOperandNames = llvm::SmallVector( @@ -151,8 +168,7 @@ static LogicalResult generateTypedefList(irdl::DialectOp &dialect, llvm::SmallVector &typeNames) { auto typeOps = dialect.getOps(); - auto range = llvm::map_range( - typeOps, [](auto &&type) { return getStrings(type).typeCppName; }); + auto range = llvm::map_range(typeOps, typeToCppName); typeNames = llvm::SmallVector(range); return success(); } @@ -160,8 +176,7 @@ generateTypedefList(irdl::DialectOp &dialect, static LogicalResult generateOpList(irdl::DialectOp &dialect, llvm::SmallVector &opNames) { auto operationOps = dialect.getOps(); - auto range = llvm::map_range( - operationOps, [](auto &&op) { return getStrings(op).opCppName; }); + auto range = llvm::map_range(operationOps, opToCppName); opNames = llvm::SmallVector(range); return success(); } @@ -174,9 +189,7 @@ static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, #include "Templates/TypeDecl.txt" ); - const auto typeStrings = getStrings(type); - fillDict(dict, typeStrings); - + fillDict(dict, getStrings(type)); typeDeclTemplate.render(output, dict); return success(); @@ -203,20 +216,26 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, dict["OP_GETTER_DECLS"] = getters; std::string buildDecls; llvm::raw_string_ostream stream{buildDecls}; - stream << llvm::formatv( - R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", + + auto resultParams = llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef name) -> std::string { return llvm::formatv("::mlir::Type {0}, ", - name); + snakeToCamel(name)); }), - ""), + ""); + + auto operandParams = llvm::join(llvm::map_range(opStrings.opOperandNames, [](StringRef name) -> std::string { return llvm::formatv("::mlir::Value {0}, ", - name); + snakeToCamel(name)); }), - "")); + ""); + + stream << llvm::formatv( + R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", + resultParams, operandParams); dict["OP_BUILD_DECLS"] = buildDecls; perOpDeclTemplate.render(output, dict); @@ -453,7 +472,7 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, return success(); } -static LogicalResult verifySymbol(irdl::DialectOp dialect) { +static LogicalResult verifySupported(irdl::DialectOp dialect) { for (auto operation : dialect.getOps()) { // scan operands of operation for (auto operands : operation.getOps()) { @@ -499,7 +518,7 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, return dialect->emitError( "dialect name must only contain letters, numbers or underscores"); - if (failed(verifySymbol(dialect))) + if (failed(verifySupported(dialect))) return failure(); llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, @@ -516,7 +535,7 @@ LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, namespacePathStream << "::" << pathElement; } - std::string cppShortName = capitalize(dialectName); + std::string cppShortName = snakeToPascal(dialectName); std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 2a8ccff4a51ee..30b8ecf7c5ab4 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -46,6 +46,6 @@ struct TestOpConversion : public OpConversionPattern { }; void registerIrdlTestDialect(mlir::DialectRegistry ®istry) { - registry.insert(); + registry.insert(); } } // namespace test From 77aaaf2333699e81d12216ac92aba2e121e24862 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 14:03:14 +0000 Subject: [PATCH 43/94] removed oplist and typelist defs --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 27 +++++++++---------- .../IRDLToCpp/Templates/OperationDef.txt | 21 --------------- .../Target/IRDLToCpp/Templates/TypeDef.txt | 9 ------- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 2 -- .../TestIRDLToCpp/TestIRDLToCppDialect.h | 4 +-- 5 files changed, 15 insertions(+), 48 deletions(-) delete mode 100644 mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 38470154f0ec7..7924378e4c2ff 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -298,9 +298,6 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, static const auto typeHeaderDefTemplate = mlir::irdl::detail::Template{ #include "Templates/TypeHeaderDef.txt" - }; - static const auto opDefTemplate = mlir::irdl::detail::Template{ -#include "Templates/OperationDef.txt" }; static const auto typeDefTemplate = mlir::irdl::detail::Template{ #include "Templates/TypeDef.txt" @@ -339,9 +336,9 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, [&](llvm::StringRef name) -> std::string { return llvm::formatv( R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { -value = {1}::{0}::get(parser.getContext()); -return ::mlir::success(!!value); -}))", + value = {1}::{0}::get(parser.getContext()); + return ::mlir::success(!!value); + }))", name, dialectStrings.namespacePath); }), "\n"); @@ -357,12 +354,7 @@ return ::mlir::success(!!value); })", std::move(typeCase)); - dict["TYPE_PRINTER"] = llvm::formatv( - R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) { - return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def) - {0} - .Default([](auto) {{ return ::mlir::failure(); }); -})", + auto typePrintCase = llvm::join(llvm::map_range(typeNames, [&](llvm::StringRef name) -> std::string { return llvm::formatv( @@ -372,7 +364,14 @@ return ::mlir::success(!!value); }))", name, dialectStrings.namespacePath); }), - "\n")); + "\n"); + dict["TYPE_PRINTER"] = llvm::formatv( + R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) { + return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def) + {0} + .Default([](auto) {{ return ::mlir::failure(); }); +})", + std::move(typePrintCase)); dict["TYPE_DEFINES"] = llvm::join(llvm::map_range(typeNames, @@ -465,7 +464,7 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, dict["OP_LIST"] = commaSeparatedOpList; dict["OP_CLASSES"] = perOpDefinitions; - opDefTemplate.render(output, dict); + output << perOpDefinitions; dialectDefTemplate.render(output, dict); output << "#endif // " << definitionMacroFlag << "\n"; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt deleted file mode 100644 index e4192b47cae87..0000000000000 --- a/mlir/lib/Target/IRDLToCpp/Templates/OperationDef.txt +++ /dev/null @@ -1,21 +0,0 @@ -/* -{0}: Comma-separated op list -{2}: Per-op definitions -*/ - -R"( -#ifdef GET_OP_LIST -#undef GET_OP_LIST - -__OP_LIST__ - -#endif // GET_OP_LIST - - -#ifdef GET_OP_CLASSES -#undef GET_OP_CLASSES - -__OP_CLASSES__ - -#endif // GET_OP_CLASSES -)" \ No newline at end of file diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index 1e770dd0935dd..570226a40b7d4 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -9,16 +9,8 @@ */ R"( -#ifdef GET_TYPEDEF_LIST -#undef GET_TYPEDEF_LIST -__TYPE_LIST__ -#endif // GET_TYPEDEF_LIST - - -#ifdef GET_TYPEDEF_CLASSES -#undef GET_TYPEDEF_CLASSES __TYPE_DEFINES__ @@ -50,5 +42,4 @@ void __DIALECT_CPP_NAME__::printType(::mlir::Type type, } __NAMESPACE_CLOSE__ -#endif // GET_TYPEDEF_CLASSES )" \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 30b8ecf7c5ab4..53dce68a20dcd 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -29,8 +29,6 @@ #include "TestIRDLToCppDialect.h" #define GEN_DIALECT_DEF -#define GET_TYPEDEF_CLASSES -#define GET_OP_CLASSES #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" namespace test { diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h index af15fda92ed93..e7a1eddc7297a 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h @@ -1,4 +1,5 @@ -//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -*-===// +//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ +//-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +16,5 @@ #define GEN_DIALECT_DECL_HEADER #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" -#undef GEN_DIALECT_DECL_HEADER #endif // MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H From bda0295e7d8b2e9c733090d0b4179db1b8c6c3d1 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 14:21:18 +0000 Subject: [PATCH 44/94] newline fix --- .../Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir index a9a0242c22303..4c8ccf1d4389c 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir @@ -20,4 +20,4 @@ irdl.dialect @test_irdl_to_cpp_2 { } } -// ----- \ No newline at end of file +// ----- From 19958685e8b88b7b52d416fc08303351aeccb64d Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 10 Mar 2025 20:37:52 +0000 Subject: [PATCH 45/94] added test for conversion --- mlir/lib/Target/IRDLToCpp/CMakeLists.txt | 4 +-- .../IRDLToCpp/Templates/PerOperationDecl.txt | 11 ++---- .../lib/Dialect/TestIRDLToCpp/CMakeLists.txt | 2 ++ .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 34 +++++++++++++++++++ .../TestIRDLToCpp/TestIRDLToCppDialect.h | 4 +++ .../{test.test.mlir => test.testd.mlir} | 0 .../TestIRDLToCpp/test_conversion.testd.mlir | 17 ++++++++++ .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 11 ++++++ mlir/tools/mlir-opt/mlir-opt.cpp | 4 ++- 9 files changed, 75 insertions(+), 12 deletions(-) rename mlir/test/lib/Dialect/TestIRDLToCpp/{test.test.mlir => test.testd.mlir} (100%) create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir diff --git a/mlir/lib/Target/IRDLToCpp/CMakeLists.txt b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt index e39fff8c804be..731f3fea37451 100644 --- a/mlir/lib/Target/IRDLToCpp/CMakeLists.txt +++ b/mlir/lib/Target/IRDLToCpp/CMakeLists.txt @@ -1,11 +1,9 @@ add_mlir_translation_library(MLIRTargetIRDLToCpp TranslationRegistration.cpp IRDLToCpp.cpp - Templates/DialectDecl.txt Templates/DialectDef.txt Templates/Header.txt - Templates/OperationDef.txt Templates/PerOperationDecl.txt Templates/PerOperationDef.txt Templates/TypeDecl.txt @@ -17,4 +15,4 @@ add_mlir_translation_library(MLIRTargetIRDLToCpp MLIRIR MLIRIRDL MLIRTranslateLib - ) +) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 0f28e61aadb62..e5f96707297ba 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -8,14 +8,11 @@ public: struct Properties { }; public: - __OP_CPP_NAME__GenericAdaptorBase(::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), odsRegions(regions) { - if (odsAttrs) - odsOpName.emplace("__DIALECT_NAME__.__OP_NAME__", odsAttrs.getContext()); - } - __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} - std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); + std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize) { + return {index, __OP_OPERAND_COUNT__}; + } const Properties &getProperties() { return properties; @@ -37,8 +34,6 @@ class __OP_CPP_NAME__GenericAdaptor : public detail::__OP_CPP_NAME__GenericAdapt using ValueT = ::llvm::detail::ValueOfRange; using Base = detail::__OP_CPP_NAME__GenericAdaptorBase; public: - __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = {}, const ::mlir::EmptyProperties &properties = {}, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} - __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {}) : __OP_CPP_NAME__GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{}), regions) {} __OP_CPP_NAME__GenericAdaptor(RangeT values, const __OP_CPP_NAME__GenericAdaptorBase &base) : Base(base), odsOperands(values) {} diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt b/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt index c3ee76f4b9e71..98a4bd3058a2a 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/CMakeLists.txt @@ -10,4 +10,6 @@ add_mlir_library(MLIRTestIRDLToCppDialect LINK_LIBS PUBLIC MLIRIR + MLIRPass + MLIRTransforms ) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 53dce68a20dcd..fa58436efb6ea 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -17,12 +17,14 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/Interfaces/InferTypeOpInterface.h" +#include "mlir/Pass/Pass.h" #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/LLVMTranslationInterface.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "mlir/Tools/mlir-translate/Translation.h" #include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/TypeSwitch.h" @@ -39,11 +41,43 @@ struct TestOpConversion : public OpConversionPattern { LogicalResult matchAndRewrite(mlir::test_irdl_to_cpp::BeefOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + rewriter.setInsertionPointAfter(op); + auto bar = rewriter.replaceOpWithNewOp( + op, op->getResultTypes().front()); + + rewriter.create( + bar.getLoc(), rewriter.getIntegerType(32), adaptor.getLhs(), + adaptor.getRhs()); return success(); } }; +struct ConvertTestDialectToSomethingPass + : PassWrapper> { + MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID( + ConvertTestDialectToSomethingPass) + + void runOnOperation() override { + MLIRContext *ctx = &getContext(); + RewritePatternSet patterns(ctx); + patterns.add(ctx); + (void)applyPatternsGreedily(getOperation(), std::move(patterns)); + } + + StringRef getArgument() const final { return "test-irdl-conversion-check"; } + StringRef getDescription() const final { + return "Checks the convertability of an irdl dialect"; + } +}; + void registerIrdlTestDialect(mlir::DialectRegistry ®istry) { registry.insert(); } + } // namespace test + +namespace mlir::test { +void registerTestIrdlTestDialectConversionPass() { + PassRegistration<::test::ConvertTestDialectToSomethingPass>(); +} +} // namespace mlir::test \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h index e7a1eddc7297a..03aa528a42ecd 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h @@ -17,4 +17,8 @@ #define GEN_DIALECT_DECL_HEADER #include "test_irdl_to_cpp.irdl.mlir.cpp.inc" +namespace test { +void registerConvertTestDialectPass(); +} + #endif // MLIR_TEST_LIB_DIALECT_TESTIRDLTOCPP_TESTIRDLTOCPPDIALECT_H diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir similarity index 100% rename from mlir/test/lib/Dialect/TestIRDLToCpp/test.test.mlir rename to mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir new file mode 100644 index 0000000000000..1ec34fad55221 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir @@ -0,0 +1,17 @@ +// RUN: mlir-opt %s --pass-pipeline="builtin.module(test-irdl-conversion-check)" | FileCheck %s +// CHECK-LABEL: module { +module { + // CHECK: func.func @test() { + // CHECK: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> i32 + // CHECK: %[[v1:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> i32 + // CHECK: %[[v2:[^ ]*]] = "test_irdl_to_cpp.hash"(%[[v0]], %[[v0]]) : (i32, i32) -> i32 + // CHECK: return + // CHECK: } + func.func @test() { + %0 = "test_irdl_to_cpp.bar"() : () -> i32 + %1 = "test_irdl_to_cpp.beef"(%0, %0) : (i32, i32) -> i32 + return + } + +// CHECK: } +} \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index e854c249edba7..13f8928a8a264 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -24,4 +24,15 @@ irdl.dialect @test_irdl_to_cpp { irdl.operands(lhs: %0, rhs: %0) irdl.results(res: %0) } + + // CHECK: irdl.type @ beef { + // CHECK: %[[v0:[^ ]*]] = irdl.any + // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) + // CHECK: irdl.results(res: %[[v0]]) + // CHECK: } + irdl.operation @hash { + %0 = irdl.any + irdl.operands(lhs: %0, rhs: %0) + irdl.results(res: %0) + } } diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 2e905521a0fbe..7865b04701574 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -125,6 +125,7 @@ void registerTestMatchReductionPass(); void registerTestMathAlgebraicSimplificationPass(); void registerTestMathPolynomialApproximationPass(); void registerTestMathToVCIXPass(); +void registerTestIrdlTestDialectConversionPass(); void registerTestMemRefDependenceCheck(); void registerTestMemRefStrideCalculation(); void registerTestMeshReshardingSpmdizationPass(); @@ -168,7 +169,7 @@ void registerTestDialect(DialectRegistry &); void registerTestDynDialect(DialectRegistry &); void registerTestTilingInterfaceTransformDialectExtension(DialectRegistry &); void registerTestTransformDialectExtension(DialectRegistry &); -void registerIrdlTestDialect(DialectRegistry&); +void registerIrdlTestDialect(DialectRegistry &); } // namespace test #ifdef MLIR_INCLUDE_TESTS @@ -295,6 +296,7 @@ void registerTestPasses() { mlir::test::registerTestVectorReductionToSPIRVDotProd(); mlir::test::registerTestVulkanRunnerPipeline(); mlir::test::registerTestWrittenToPass(); + mlir::test::registerTestIrdlTestDialectConversionPass(); #if MLIR_ENABLE_PDL_IN_PATTERNMATCH mlir::test::registerTestDialectConversionPasses(); mlir::test::registerTestPDLByteCodePass(); From 4a9735e28ab30ce9b238ec1eb3021ceadd7eca37 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 11 Mar 2025 09:49:38 +0000 Subject: [PATCH 46/94] new lines, macro guard documentation --- mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 9 ++++++++- mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir | 2 +- .../lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h index c9eee3e49c4a6..db46636fae917 100644 --- a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -21,7 +21,14 @@ namespace irdl { /// Translates an IRDL dialect definition to a C++ definition that can be used /// with MLIR. /// -/// TODO: Document define flags to obtain declaration or definition. +/// As with TableGen declarations, the following preprocessor macros will +/// generate the corresponding code: +/// +/// // This define generates code for the dialect's class declarations +/// #define GEN_DIALECT_DECL_HEADER +/// +/// // This define generates code for the dialect's class definitions +/// #define GEN_DIALECT_DEF LogicalResult translateIRDLDialectToCpp(irdl::DialectOp dialect, raw_ostream &output); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir index 5e97e9d3de69a..672e1ddf85acf 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir @@ -2,4 +2,4 @@ module { // CHECK: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo -} \ No newline at end of file +} diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir index 1ec34fad55221..f6233ee18190a 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_conversion.testd.mlir @@ -14,4 +14,4 @@ module { } // CHECK: } -} \ No newline at end of file +} From 447e474368cfcc4af6687d527bc655434f6da874 Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Tue, 18 Mar 2025 09:46:36 +0000 Subject: [PATCH 47/94] Update mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Théo Degioanni <30992420+Moxinilian@users.noreply.github.com> --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 27 +++++++++---------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 7924378e4c2ff..873e9b88e42eb 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -60,32 +60,23 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } -static std::string snakeToCamel(llvm::StringRef in) { - std::string output{}; +static std::string snakeToCamel(llvm::StringRef in, bool capitalize = false) { + std::string output; output.reserve(in.size()); - for (size_t i = 0; i < in.size(); ++i) { - if (in[i] == '_' && i + 1 < in.size()) { - output += toupper(in[i + 1]); - ++i; + + for (char c : in) { + if (c == '_') { + capitalize = true; } else { - output += in[i]; + output += capitalize ? toupper(c) : c; + capitalize = false; } } return output; } static std::string snakeToPascal(llvm::StringRef in) { - std::string output{static_cast(toupper(in.front()))}; - output.reserve(in.size()); - for (size_t i = 1; i < in.size(); ++i) { - if (in[i] == '_' && i + 1 < in.size()) { - output += toupper(in[i + 1]); - ++i; - } else { - output += in[i]; - } - } - return output; + return snakeToCamel(in, /*capitalize=*/true); } static std::string typeToCppName(irdl::TypeOp type) { From edc9fa244123782f7d47c381f428990a3d0cf869 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 18 Mar 2025 09:50:10 +0000 Subject: [PATCH 48/94] simple PR changes --- mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index fa58436efb6ea..3e7076d7f5803 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -54,9 +54,6 @@ struct TestOpConversion : public OpConversionPattern { struct ConvertTestDialectToSomethingPass : PassWrapper> { - MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID( - ConvertTestDialectToSomethingPass) - void runOnOperation() override { MLIRContext *ctx = &getContext(); RewritePatternSet patterns(ctx); @@ -80,4 +77,4 @@ namespace mlir::test { void registerTestIrdlTestDialectConversionPass() { PassRegistration<::test::ConvertTestDialectToSomethingPass>(); } -} // namespace mlir::test \ No newline at end of file +} // namespace mlir::test From 21eada6946156ac8bac2699d86f2771af02f23e7 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 18 Mar 2025 10:35:21 +0000 Subject: [PATCH 49/94] set up for multiple dialect conversions --- .../include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 2 +- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 116 ++++++++++-------- .../IRDLToCpp/Templates/PerOperationDecl.txt | 11 ++ .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 26 +--- 4 files changed, 85 insertions(+), 70 deletions(-) diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h index db46636fae917..bfafde1c60150 100644 --- a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -29,7 +29,7 @@ namespace irdl { /// /// // This define generates code for the dialect's class definitions /// #define GEN_DIALECT_DEF -LogicalResult translateIRDLDialectToCpp(irdl::DialectOp dialect, +LogicalResult translateIRDLDialectToCpp(llvm::ArrayRef dialect, raw_ostream &output); } // namespace irdl diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 873e9b88e42eb..0558b3536399d 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -76,7 +76,7 @@ static std::string snakeToCamel(llvm::StringRef in, bool capitalize = false) { } static std::string snakeToPascal(llvm::StringRef in) { - return snakeToCamel(in, /*capitalize=*/true); + return snakeToCamel(in, /*capitalize=*/true); } static std::string typeToCppName(irdl::TypeOp type) { @@ -490,61 +490,81 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { return success(); } -LogicalResult irdl::translateIRDLDialectToCpp(irdl::DialectOp dialect, - raw_ostream &output) { +LogicalResult +irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, + raw_ostream &output) { static const auto typeDefTempl = detail::Template( #include "Templates/TypeDef.txt" ); - StringRef dialectName = dialect.getSymName(); + llvm::LogicalResult result = success(); - // TODO: deal with no more constraints than the verifier allows. - if (dialectName.size() < 1) - return dialect->emitError("dialect name must be more than one character"); - if (!llvm::isAlpha(dialectName[0])) - return dialect->emitError("dialect name must start with a letter"); - if (!llvm::all_of(dialectName, - [](char c) { return llvm::isAlnum(c) || c == '_'; })) - return dialect->emitError( - "dialect name must only contain letters, numbers or underscores"); + for (auto dialect : dialects) { + StringRef dialectName = dialect.getSymName(); - if (failed(verifySupported(dialect))) - return failure(); - - llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, - dialectName}; - std::string namespaceOpen; - std::string namespaceClose; - std::string namespacePath; - llvm::raw_string_ostream namespaceOpenStream(namespaceOpen); - llvm::raw_string_ostream namespaceCloseStream(namespaceClose); - llvm::raw_string_ostream namespacePathStream(namespacePath); - for (auto &pathElement : namespaceAbsolutePath) { - namespaceOpenStream << "namespace " << pathElement << " {\n"; - namespaceCloseStream << "} // namespace " << pathElement << "\n"; - namespacePathStream << "::" << pathElement; - } - - std::string cppShortName = snakeToPascal(dialectName); - std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); - std::string cppName = llvm::formatv("{0}Dialect", cppShortName); - - DialectStrings dialectStrings; - dialectStrings.dialectName = dialectName; - dialectStrings.dialectBaseTypeName = dialectBaseTypeName; - dialectStrings.dialectCppName = cppName; - dialectStrings.dialectCppShortName = cppShortName; - dialectStrings.namespaceOpen = namespaceOpen; - dialectStrings.namespaceClose = namespaceClose; - dialectStrings.namespacePath = namespacePath; + // TODO: deal with no more constraints than the verifier allows. + if (dialectName.size() < 1) { + result = + dialect->emitError("dialect name must be more than one character"); + continue; + } + if (!llvm::isAlpha(dialectName[0])) { + result = dialect->emitError("dialect name must start with a letter"); + continue; + } + if (!llvm::all_of(dialectName, + [](char c) { return llvm::isAlnum(c) || c == '_'; })) { + result = dialect->emitError( + "dialect name must only contain letters, numbers or underscores"); + continue; + } - output << headerTemplateText; + if (failed(verifySupported(dialect))) + result = failure(); + + llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, + dialectName}; + std::string namespaceOpen; + std::string namespaceClose; + std::string namespacePath; + llvm::raw_string_ostream namespaceOpenStream(namespaceOpen); + llvm::raw_string_ostream namespaceCloseStream(namespaceClose); + llvm::raw_string_ostream namespacePathStream(namespacePath); + for (auto &pathElement : namespaceAbsolutePath) { + namespaceOpenStream << "namespace " << pathElement << " {\n"; + namespaceCloseStream << "} // namespace " << pathElement << "\n"; + namespacePathStream << "::" << pathElement; + } - if (failed(generateInclude(dialect, output, dialectStrings))) - return failure(); + std::string cppShortName = snakeToPascal(dialectName); + std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); + std::string cppName = llvm::formatv("{0}Dialect", cppShortName); + + DialectStrings dialectStrings; + dialectStrings.dialectName = dialectName; + dialectStrings.dialectBaseTypeName = dialectBaseTypeName; + dialectStrings.dialectCppName = cppName; + dialectStrings.dialectCppShortName = cppShortName; + dialectStrings.namespaceOpen = namespaceOpen; + dialectStrings.namespaceClose = namespaceClose; + dialectStrings.namespacePath = namespacePath; + + output << headerTemplateText; + + if (failed(generateInclude(dialect, output, dialectStrings))) { + dialect->emitError("Error in Dialect " + dialectName + + " while generating headers"); + result = failure(); + continue; + } - if (failed(generateLib(dialect, output, dialectStrings))) - return failure(); + if (failed(generateLib(dialect, output, dialectStrings))) { + dialect->emitError("Error in Dialect " + dialectName + + " while generating library"); + result = failure(); + continue; + } + } - return success(); + return result; } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index e5f96707297ba..74dbcaa247038 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -108,12 +108,23 @@ public: std::pair getODSOperandIndexAndLength(unsigned index) { return {index, __OP_OPERAND_COUNT__}; } + ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } + std::pair getODSResultIndexAndLength(unsigned index) { + return {index, __OP_RESULT_COUNT__}; + } + + ::mlir::Operation::result_range getODSResults(unsigned index) { + auto valueRange = getODSResultIndexAndLength(index); + return {std::next(getOperation()->result_begin(), valueRange.first), + std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; + } + __OP_GETTER_DECLS__ __OP_BUILD_DECLS__ diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 1c31b31e8e938..076a8027965c5 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -82,36 +82,20 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { return failure(); auto moduleOp = llvm::cast(*op); + llvm::SmallVector dialects{ + moduleOp.getOps()}; if (!verifyDiagnostics) { SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); + if (failed(irdl::translateIRDLDialectToCpp(dialects, output->os()))) + return failure(); - for (Operation &op : moduleOp.getOps()) { - auto dialectOp = llvm::dyn_cast(op); - if (!dialectOp) - continue; - - // TODO: accept multiple operations in translation to not generate headers - // multiple times. - if (failed(irdl::translateIRDLDialectToCpp(dialectOp, output->os()))) { - return failure(); - } - } output->keep(); return success(); } SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &ctx); - - for (Operation &op : moduleOp.getOps()) { - auto dialectOp = llvm::dyn_cast(op); - if (!dialectOp) - continue; - - // TODO: accept multiple operations in translation to not generate headers - // multiple times. - ((void)irdl::translateIRDLDialectToCpp(dialectOp, output->os())); - } + ((void)irdl::translateIRDLDialectToCpp(dialects, output->os())); return sourceMgrHandler.verify(); } From 1c5c3c1faa40fb43ae9031ac0d73f63f2b0d5aae Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 18 Mar 2025 14:32:01 +0000 Subject: [PATCH 50/94] conversion test works again --- .../Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 3e7076d7f5803..cc10506d7b804 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -36,14 +36,14 @@ namespace test { using namespace mlir; struct TestOpConversion : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; + using OpConversionPattern::OpConversionPattern; LogicalResult matchAndRewrite(mlir::test_irdl_to_cpp::BeefOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - rewriter.setInsertionPointAfter(op); auto bar = rewriter.replaceOpWithNewOp( op, op->getResultTypes().front()); + rewriter.setInsertionPointAfter(bar); rewriter.create( bar.getLoc(), rewriter.getIntegerType(32), adaptor.getLhs(), @@ -58,7 +58,13 @@ struct ConvertTestDialectToSomethingPass MLIRContext *ctx = &getContext(); RewritePatternSet patterns(ctx); patterns.add(ctx); - (void)applyPatternsGreedily(getOperation(), std::move(patterns)); + ConversionTarget target(getContext()); + target.addIllegalOp(); + target.addLegalOp(); + target.addLegalOp(); + if (failed(applyPartialConversion(getOperation(), target, + std::move(patterns)))) + signalPassFailure(); } StringRef getArgument() const final { return "test-irdl-conversion-check"; } From 26f580e06beb91b7b2b84ba30734b9ac3c5e466c Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 18 Mar 2025 14:45:17 +0000 Subject: [PATCH 51/94] getODSResults --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 15 ++++++++++++--- .../IRDLToCpp/Templates/PerOperationDecl.txt | 5 +++-- .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 4 ++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 0558b3536399d..7859adc85d2c6 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -195,16 +195,25 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto opStrings = getStrings(op); fillDict(dict, opStrings); - auto getters = std::string{}; + auto op_getters = std::string{}; + auto res_getters = std::string{}; for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { const auto &op = snakeToPascal(opStrings.opOperandNames[i]); - getters += llvm::formatv( + op_getters += llvm::formatv( "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n ", op, i); } + for (size_t i = 0; i < opStrings.opResultNames.size(); ++i) { + const auto &op = snakeToPascal(opStrings.opResultNames[i]); + res_getters += llvm::formatv( + R"(::mlir::TypedValue<::mlir::Type> get{0}() { return ::llvm::cast<::mlir::TypedValue<::mlir::Type>>(getODSResults({1}).front()); } + )", + op, i); + } - dict["OP_GETTER_DECLS"] = getters; + dict["OP_OPERAND_GETTER_DECLS"] = op_getters; + dict["OP_RESULT_GETTER_DECLS"] = res_getters; std::string buildDecls; llvm::raw_string_ostream stream{buildDecls}; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 74dbcaa247038..2f9d736d2a7ce 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -55,7 +55,7 @@ public: return odsOperands; } - __OP_GETTER_DECLS__ + __OP_OPERAND_GETTER_DECLS__ private: RangeT odsOperands; @@ -125,7 +125,8 @@ public: std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } - __OP_GETTER_DECLS__ + __OP_OPERAND_GETTER_DECLS__ + __OP_RESULT_GETTER_DECLS__ __OP_BUILD_DECLS__ static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index 13f8928a8a264..6cca614264ba1 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -14,7 +14,7 @@ irdl.dialect @test_irdl_to_cpp { } - // CHECK: irdl.type @ beef { + // CHECK: irdl.type @beef { // CHECK: %[[v0:[^ ]*]] = irdl.any // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) // CHECK: irdl.results(res: %[[v0]]) @@ -25,7 +25,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.results(res: %0) } - // CHECK: irdl.type @ beef { + // CHECK: irdl.type @hash { // CHECK: %[[v0:[^ ]*]] = irdl.any // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) // CHECK: irdl.results(res: %[[v0]]) From 732e60652df33616365b831cd6f76fdfdf28d16a Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 09:45:57 +0000 Subject: [PATCH 52/94] fixed header naming --- mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h index bfafde1c60150..2587cb4b65638 100644 --- a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -29,8 +29,9 @@ namespace irdl { /// /// // This define generates code for the dialect's class definitions /// #define GEN_DIALECT_DEF -LogicalResult translateIRDLDialectToCpp(llvm::ArrayRef dialect, - raw_ostream &output); +LogicalResult +translateIRDLDialectToCpp(llvm::ArrayRef dialects, + raw_ostream &output); } // namespace irdl } // namespace mlir From 44976b6b8a50f6d06bada7f54f4bd62684c8a139 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 11:20:41 +0000 Subject: [PATCH 53/94] symbol verification --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 110 ++++++++++++------ .../test_irdl_to_cpp_invalid_names.irdl.mlir | 18 +++ ...o_cpp_invalid_unsupported_types.irdl.mlir} | 4 +- 3 files changed, 93 insertions(+), 39 deletions(-) create mode 100644 mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir rename mlir/test/lib/Dialect/TestIRDLToCpp/{test_irdl_to_cpp_invalid.irdl.mlir => test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir} (100%) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 7859adc85d2c6..df9e3c02c2d4b 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" @@ -60,6 +61,30 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } +static llvm::LogicalResult isSnakeCase(llvm::StringRef in, + mlir::Operation *loc) { + bool allowUnderscore = false; + for (auto &elem : in) { + if (elem == '_') { + if (!allowUnderscore) + return loc->emitError( + "Error in dialect name: No leading or double underscores allowed."); + } else { + if (!isalnum(elem)) + return loc->emitError("Error in dialect name: Only numbers and " + "lower-case characters allowed"); + + if (llvm::isUpper(elem)) + return loc->emitError( + "Error in dialect name: Upper-case characters are not allowed"); + } + + allowUnderscore = elem != '_'; + } + + return success(); +} + static std::string snakeToCamel(llvm::StringRef in, bool capitalize = false) { std::string output; output.reserve(in.size()); @@ -472,30 +497,56 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, } static LogicalResult verifySupported(irdl::DialectOp dialect) { - for (auto operation : dialect.getOps()) { - // scan operands of operation - for (auto operands : operation.getOps()) { - for (auto operand : operands.getOperands()) { - if (!llvm::isa(operand.getDefiningOp())) { - return operands.emitError( - "IRDL C++ translation only supports irdl.any " - "constraint for types"); - } - } - } + if (failed(isSnakeCase(dialect.getSymName(), dialect))) + return failure(); - // scan results of operation - for (auto results : operation.getOps()) { - for (auto operand : results.getOperands()) { - if (!llvm::isa(operand.getDefiningOp())) { - return results.emitError( - "IRDL C++ translation only supports irdl.any " - "constraint for types"); - } - } + llvm::SmallVector frontier; + for (auto &block : dialect.getBody()) { + for (auto &op : block) { + llvm::TypeSwitch(&op) + .Case([&frontier](irdl::TypeOp type) { + for (auto &typeblocks : type.getBody()) + for (auto &typeOps : typeblocks) + frontier.push_back(&typeOps); + }) + .Case([&frontier](irdl::OperationOp op) { + for (auto &opblocks : op.getBody()) + for (auto &opOps : opblocks) + frontier.push_back(&opOps); + }); } } + while (frontier.size()) { + auto *front = frontier.back(); + frontier.pop_back(); + + auto res = + llvm::TypeSwitch(front) + .Case([](irdl::AnyOfOp op) -> LogicalResult { + return op.emitError("IRDL C++ translation only supports irdl.any " + "constraint for types"); + }) + .Case([](irdl::AllOfOp op) -> LogicalResult { + return op.emitError("IRDL C++ translation only supports irdl.any " + "constraint for types"); + }) + .Case( + [](irdl::ParametricOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation only supports irdl.any " + "constraint for types"); + }) + .Case([](irdl::IsOp op) -> LogicalResult { + return op.emitError("IRDL C++ translation only supports irdl.any " + "constraint for types"); + }) + .Default(success()); + + if (failed(res)) + return res; + } + return success(); } @@ -511,26 +562,11 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, for (auto dialect : dialects) { StringRef dialectName = dialect.getSymName(); - // TODO: deal with no more constraints than the verifier allows. - if (dialectName.size() < 1) { - result = - dialect->emitError("dialect name must be more than one character"); - continue; - } - if (!llvm::isAlpha(dialectName[0])) { - result = dialect->emitError("dialect name must start with a letter"); - continue; - } - if (!llvm::all_of(dialectName, - [](char c) { return llvm::isAlnum(c) || c == '_'; })) { - result = dialect->emitError( - "dialect name must only contain letters, numbers or underscores"); + if (failed(verifySupported(dialect))) { + result = failure(); continue; } - if (failed(verifySupported(dialect))) - result = failure(); - llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; std::string namespaceOpen; diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir new file mode 100644 index 0000000000000..d46b266db7317 --- /dev/null +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir @@ -0,0 +1,18 @@ +// RUN: mlir-irdl-to-cpp %s --verify-diagnostics +// expected-error@+1 {{Error in dialect name: No leading or double underscores allowed.}} +irdl.dialect @_no_leading_underscore { +} + +// expected-error@+1 {{Error in dialect name: No leading or double underscores allowed.}} +irdl.dialect @_no__double__underscores { +} + +// expected-error@+1 {{Error in dialect name: Upper-case characters are not allowed}} +irdl.dialect @NoUpperCase { +} + +// expected-error@+1 {{Error in dialect name: Only numbers and lower-case characters allowed}} +irdl.dialect @no_weird_symbol$ { +} + +// ----- \ No newline at end of file diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir similarity index 100% rename from mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir rename to mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index 4c8ccf1d4389c..f76d16054df50 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -2,8 +2,8 @@ irdl.dialect @test_irdl_to_cpp { irdl.operation @results_no_any_of { %0 = irdl.any - %1 = irdl.any_of(%0, %0) // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + %1 = irdl.any_of(%0, %0) irdl.results(res: %1) } } @@ -13,8 +13,8 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp_2 { irdl.operation @operands_no_any_of { %0 = irdl.any - %1 = irdl.any_of(%0, %0) // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + %1 = irdl.any_of(%0, %0) irdl.operands(test: %1) irdl.results(res: %0) } From 318f759e57868d4febb81dec12a5297972821dc2 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 12:52:09 +0000 Subject: [PATCH 54/94] invalid names --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 70 ++++++++------- .../test_irdl_to_cpp_invalid_names.irdl.mlir | 86 +++++++++++++++++-- 2 files changed, 120 insertions(+), 36 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index df9e3c02c2d4b..27e9e30671fd0 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -68,15 +68,20 @@ static llvm::LogicalResult isSnakeCase(llvm::StringRef in, if (elem == '_') { if (!allowUnderscore) return loc->emitError( - "Error in dialect name: No leading or double underscores allowed."); + llvm::formatv("Error in symbol name `{}`: No leading or double " + "underscores allowed.", + in)); } else { if (!isalnum(elem)) - return loc->emitError("Error in dialect name: Only numbers and " - "lower-case characters allowed"); + return loc->emitError( + llvm::formatv("Error in symbol name `{}`: Only numbers and " + "lower-case characters allowed.", + in)); if (llvm::isUpper(elem)) - return loc->emitError( - "Error in dialect name: Upper-case characters are not allowed"); + return loc->emitError(llvm::formatv( + "Error in symbol name `{}`: Upper-case characters are not allowed.", + in)); } allowUnderscore = elem != '_'; @@ -500,29 +505,30 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { if (failed(isSnakeCase(dialect.getSymName(), dialect))) return failure(); - llvm::SmallVector frontier; - for (auto &block : dialect.getBody()) { - for (auto &op : block) { - llvm::TypeSwitch(&op) - .Case([&frontier](irdl::TypeOp type) { - for (auto &typeblocks : type.getBody()) - for (auto &typeOps : typeblocks) - frontier.push_back(&typeOps); - }) - .Case([&frontier](irdl::OperationOp op) { - for (auto &opblocks : op.getBody()) - for (auto &opOps : opblocks) - frontier.push_back(&opOps); - }); - } - } - - while (frontier.size()) { - auto *front = frontier.back(); - frontier.pop_back(); - - auto res = - llvm::TypeSwitch(front) + LogicalResult res = success(); + dialect.walk([&](mlir::Operation *op) { + res = + llvm::TypeSwitch(op) + .Case([](irdl::TypeOp op) -> LogicalResult { + return isSnakeCase(op.getSymName(), op); + }) + .Case([](irdl::OperationOp op) -> LogicalResult { + return isSnakeCase(op.getSymName(), op); + }) + .Case([](irdl::OperandsOp op) -> LogicalResult { + for (auto &elem : op.getNames()) + if (failed(isSnakeCase(llvm::dyn_cast(elem), + op))) + return failure(); + return success(); + }) + .Case([](irdl::ResultsOp op) -> LogicalResult { + for (auto &elem : op.getNames()) + if (failed(isSnakeCase(llvm::dyn_cast(elem), + op))) + return failure(); + return success(); + }) .Case([](irdl::AnyOfOp op) -> LogicalResult { return op.emitError("IRDL C++ translation only supports irdl.any " "constraint for types"); @@ -544,10 +550,12 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { .Default(success()); if (failed(res)) - return res; - } + return WalkResult::interrupt(); - return success(); + return WalkResult::advance(); + }); + + return res; } LogicalResult diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir index d46b266db7317..0e1292c90f7ac 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir @@ -1,18 +1,94 @@ // RUN: mlir-irdl-to-cpp %s --verify-diagnostics -// expected-error@+1 {{Error in dialect name: No leading or double underscores allowed.}} +// expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} irdl.dialect @_no_leading_underscore { } -// expected-error@+1 {{Error in dialect name: No leading or double underscores allowed.}} +// ----- + +// expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} irdl.dialect @_no__double__underscores { } -// expected-error@+1 {{Error in dialect name: Upper-case characters are not allowed}} +// ----- + +// expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed}} irdl.dialect @NoUpperCase { } -// expected-error@+1 {{Error in dialect name: Only numbers and lower-case characters allowed}} +// ----- + +// expected-error@+1 {{Error in symbol name `no_weird_symbol$`: Only numbers and lower-case characters allowed}} irdl.dialect @no_weird_symbol$ { } -// ----- \ No newline at end of file +// ----- + +irdl.dialect @test_dialect { + // expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} + irdl.operation @_no_leading_underscore { + %0 = irdl.any + irdl.results(res: %0) + } +} + +// ----- + +irdl.dialect @test_dialect2 { + // expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} + irdl.operation @_no__double__underscores { + %0 = irdl.any + irdl.results(res: %0) + } +} + +// ----- + +irdl.dialect @test_dialect3 { + // expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed.}} + irdl.operation @NoUpperCase { + %0 = irdl.any + irdl.results(res: %0) + } +} + +// ----- + +irdl.dialect @test_dialect4 { + // expected-error@+1 {{Error in symbol name `no_weird_symbol$`: Only numbers and lower-case characters allowed.}} + irdl.operation @no_weird_symbol$ { + %0 = irdl.any + irdl.results(res: %0) + } +} + +// ----- + +irdl.dialect @test_dialect5 { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} + irdl.results(_no_leading_underscore: %0) + } +} + +// ----- + +irdl.dialect @test_dialect6 { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} + irdl.results(_no__double__underscores: %0) + } +} + +// ----- + +irdl.dialect @test_dialect7 { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed.}} + irdl.results(NoUpperCase: %0) + } +} + +// ----- From 6d1beac5c8b6b7f69c53c3773144b6db83d131de Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 12:57:59 +0000 Subject: [PATCH 55/94] check every irdl op --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 31 ++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 27e9e30671fd0..3813b001bdc8f 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -529,6 +529,15 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { return failure(); return success(); }) + .Case([](irdl::AttributeOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support attributes."); + }) + .Case( + [](irdl::AttributesOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support attributes."); + }) .Case([](irdl::AnyOfOp op) -> LogicalResult { return op.emitError("IRDL C++ translation only supports irdl.any " "constraint for types"); @@ -537,16 +546,32 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { return op.emitError("IRDL C++ translation only supports irdl.any " "constraint for types"); }) + .Case([](irdl::ParametersOp op) + -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support type parameters."); + }) .Case( [](irdl::ParametricOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation only supports irdl.any " - "constraint for types"); + return op.emitError("IRDL C++ translation does not yet " + "support parametric operations."); }) + .Case([](irdl::RegionOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support regions."); + }) + .Case([](irdl::RegionsOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support regions."); + }) .Case([](irdl::IsOp op) -> LogicalResult { return op.emitError("IRDL C++ translation only supports irdl.any " "constraint for types"); }) + .Case([](irdl::CPredOp op) -> LogicalResult { + return op.emitError("IRDL C++ translation only supports irdl.any " + "constraint for types"); + }) .Default(success()); if (failed(res)) From 16b0414e4c768c6aa9eaf5e251c4f8e1bcbbffd9 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 13:12:56 +0000 Subject: [PATCH 56/94] unsupported irdl ops --- ...to_cpp_invalid_unsupported_types.irdl.mlir | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index f76d16054df50..a88cc15484680 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -9,15 +9,63 @@ irdl.dialect @test_irdl_to_cpp { } // ----- -// no support for split-buffer yet irdl.dialect @test_irdl_to_cpp_2 { irdl.operation @operands_no_any_of { %0 = irdl.any // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} - %1 = irdl.any_of(%0, %0) + %1 = irdl.all_of(%0, %0) irdl.operands(test: %1) irdl.results(res: %0) } } // ----- + +irdl.dialect @test_irdl_to_cpp_3 { + // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + irdl.attribute @no_attrs +} + +// ----- + +irdl.dialect @test_irdl_to_cpp_4 { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + irdl.attributes { + "attr" = %0 + } + } +} + +// ----- + +irdl.dialect @test_irdl_to_cpp_5 { + irdl.type @ty { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation does not yet support type parameters.}} + irdl.parameters(ty: %0) + } +} + +// ----- + +irdl.dialect @test_irdl_to_cpp_6 { + irdl.operation @test_op { + // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + %0 = irdl.region() + irdl.regions(reg: %0) + } + +} + +// ----- + +irdl.dialect @test_irdl_to_cpp_7 { + irdl.operation @test_op { + // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + irdl.regions() + } + +} + From 05fa3a805cdfea57bbb19a1c975ea625397e4750 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 14:13:52 +0000 Subject: [PATCH 57/94] base types --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 4 ++++ mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir | 2 +- ...t_irdl_to_cpp_invalid_unsupported_types.irdl.mlir | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 3813b001bdc8f..f834fb2e03a1b 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -546,6 +546,10 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { return op.emitError("IRDL C++ translation only supports irdl.any " "constraint for types"); }) + .Case([](irdl::BaseOp op) -> LogicalResult { + return op.emitError( + "IRDL C++ translation does not yet support base types."); + }) .Case([](irdl::ParametersOp op) -> LogicalResult { return op.emitError( diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir index 672e1ddf85acf..34b5632daa5ab 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir @@ -1,5 +1,5 @@ // RUN: mlir-opt %s | FileCheck %s +// CHECK: module { module { - // CHECK: %[[v0:[^ ]*]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index a88cc15484680..a488f5177c360 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -69,3 +69,15 @@ irdl.dialect @test_irdl_to_cpp_7 { } +// ----- + +irdl.dialect @test_irdl_to_cpp_8 { + irdl.type @test_base + + irdl.type @test_derived { + // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} + %0 = irdl.base "!builtin.integer" + } + +} + From ef0d97ea2bdd536404d84d4400a7d53733a903d9 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 14:15:46 +0000 Subject: [PATCH 58/94] simplified test --- .../test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir | 2 -- 1 file changed, 2 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index a488f5177c360..7b3dbfbe2b949 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -72,8 +72,6 @@ irdl.dialect @test_irdl_to_cpp_7 { // ----- irdl.dialect @test_irdl_to_cpp_8 { - irdl.type @test_base - irdl.type @test_derived { // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} %0 = irdl.base "!builtin.integer" From 91d6f80129b9977e0ec659b5bca8ecf69bc665e5 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 24 Mar 2025 16:43:38 +0000 Subject: [PATCH 59/94] split file works omg cleanup needed --- mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td | 2 + mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 57 ++++++++-- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 20 ---- .../IRDLToCpp/Templates/PerOperationDecl.txt | 4 + .../test_irdl_to_cpp_invalid_names.irdl.mlir | 32 +++--- ...to_cpp_invalid_unsupported_types.irdl.mlir | 4 +- .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 103 ++++++++++++------ 7 files changed, 140 insertions(+), 82 deletions(-) diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td index f3bc3497500e7..2e640de2c4965 100644 --- a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td +++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td @@ -91,6 +91,7 @@ def IRDL_TypeOp : IRDL_Op<"type", let regions = (region SizedRegion<1>:$body); let assemblyFormat = "$sym_name attr-dict-with-keyword custom($body)"; + let hasVerifier = 1; } def IRDL_AttributeOp : IRDL_Op<"attribute", @@ -202,6 +203,7 @@ def IRDL_OperationOp : IRDL_Op<"operation", let assemblyFormat = "$sym_name attr-dict-with-keyword custom($body)"; let hasRegionVerifier = true; + let hasVerifier = 1; } def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> { diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index c0778d478619a..e56182aaac08e 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -74,13 +74,54 @@ static void printSingleBlockRegion(OpAsmPrinter &p, Operation *op, if (!region.getBlocks().front().empty()) p.printRegion(region); } +static llvm::LogicalResult isSnakeCase(llvm::StringRef in, mlir::Operation *loc, + const Twine &label) { + if (in.empty()) + return loc->emitError("name of ") << label << " is empty"; + + bool allowUnderscore = false; + for (auto &elem : in) { + if (elem == '_') { + if (!allowUnderscore) + return loc->emitError("name of ") + << label << " \"" << in + << "\" should not contain leading or double underscores"; + } else { + if (!isalnum(elem)) + return loc->emitError("name of ") + << label << " \"" << in + << "\" must contain only lowercase letters, digits and " + "underscores"; + + if (llvm::isUpper(elem)) + return loc->emitError("name of ") + << label << " \"" << in + << "\" should not contain uppercase letters"; + } + + allowUnderscore = elem != '_'; + } + + return success(); +} LogicalResult DialectOp::verify() { if (!Dialect::isValidNamespace(getName())) return emitOpError("invalid dialect name"); + if (failed(isSnakeCase(getName(), getOperation(), "dialect"))) + return failure(); + return success(); } +LogicalResult OperationOp::verify() { + return isSnakeCase(getName(), getOperation(), "operation"); +} + +LogicalResult TypeOp::verify() { + return isSnakeCase(getName(), getOperation(), "type"); +} + LogicalResult OperationOp::verifyRegions() { // Stores pairs of value kinds and the list of names of values of this kind in // the operation. @@ -133,18 +174,10 @@ static LogicalResult verifyNames(Operation *op, StringRef kindName, DenseMap nameMap; for (auto [i, name] : llvm::enumerate(names)) { StringRef nameRef = llvm::cast(name).getValue(); - if (nameRef.empty()) - return op->emitOpError() - << "name of " << kindName << " #" << i << " is empty"; - if (!llvm::isAlpha(nameRef[0]) && nameRef[0] != '_') - return op->emitOpError() - << "name of " << kindName << " #" << i - << " must start with either a letter or an underscore"; - if (llvm::any_of(nameRef, - [](char c) { return !llvm::isAlnum(c) && c != '_'; })) - return op->emitOpError() - << "name of " << kindName << " #" << i - << " must contain only letters, digits and underscores"; + auto verifyNameRef = isSnakeCase(nameRef, op, kindName); + if (failed(verifyNameRef)) + return verifyNameRef; + if (nameMap.contains(nameRef)) return op->emitOpError() << "name of " << kindName << " #" << i << " is a duplicate of the name of " << kindName diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index f834fb2e03a1b..1890f2c374e85 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -509,26 +509,6 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { dialect.walk([&](mlir::Operation *op) { res = llvm::TypeSwitch(op) - .Case([](irdl::TypeOp op) -> LogicalResult { - return isSnakeCase(op.getSymName(), op); - }) - .Case([](irdl::OperationOp op) -> LogicalResult { - return isSnakeCase(op.getSymName(), op); - }) - .Case([](irdl::OperandsOp op) -> LogicalResult { - for (auto &elem : op.getNames()) - if (failed(isSnakeCase(llvm::dyn_cast(elem), - op))) - return failure(); - return success(); - }) - .Case([](irdl::ResultsOp op) -> LogicalResult { - for (auto &elem : op.getNames()) - if (failed(isSnakeCase(llvm::dyn_cast(elem), - op))) - return failure(); - return success(); - }) .Case([](irdl::AttributeOp op) -> LogicalResult { return op.emitError( "IRDL C++ translation does not yet support attributes."); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 2f9d736d2a7ce..a75d87d5b45fc 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -1,4 +1,8 @@ R"( +//===----------------------------------------------------------------------===// +// __NAMESPACE_PATH__::__OP_CPP_NAME__ declarations +//===----------------------------------------------------------------------===// + __NAMESPACE_OPEN__ namespace detail { diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir index 0e1292c90f7ac..27d85f5456c14 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir @@ -1,30 +1,30 @@ -// RUN: mlir-irdl-to-cpp %s --verify-diagnostics -// expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} +// RUN: mlir-irdl-to-cpp %s --verify-diagnostics --split-input-file +// expected-error@+1 {{name of dialect "_no_leading_underscore" should not contain leading or double underscores}} irdl.dialect @_no_leading_underscore { } // ----- -// expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} -irdl.dialect @_no__double__underscores { +// expected-error@+1 {{name of dialect "no__double__underscores" should not contain leading or double underscores}} +irdl.dialect @no__double__underscores { } // ----- -// expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed}} +// expected-error@+1 {{name of dialect "NoUpperCase" should not contain uppercase letters}} irdl.dialect @NoUpperCase { } // ----- -// expected-error@+1 {{Error in symbol name `no_weird_symbol$`: Only numbers and lower-case characters allowed}} +// expected-error@+1 {{name of dialect "no_weird_symbol$" must contain only lowercase letters, digits and underscores}} irdl.dialect @no_weird_symbol$ { } // ----- irdl.dialect @test_dialect { - // expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} + // expected-error@+1 {{name of operation "_no_leading_underscore" should not contain leading or double underscores}} irdl.operation @_no_leading_underscore { %0 = irdl.any irdl.results(res: %0) @@ -33,9 +33,9 @@ irdl.dialect @test_dialect { // ----- -irdl.dialect @test_dialect2 { - // expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} - irdl.operation @_no__double__underscores { +irdl.dialect @test_dialect { + // expected-error@+1 {{name of operation "no__double__underscores" should not contain leading or double underscores}} + irdl.operation @no__double__underscores { %0 = irdl.any irdl.results(res: %0) } @@ -44,7 +44,7 @@ irdl.dialect @test_dialect2 { // ----- irdl.dialect @test_dialect3 { - // expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed.}} + // expected-error@+1 {{name of operation "NoUpperCase" should not contain uppercase letters}} irdl.operation @NoUpperCase { %0 = irdl.any irdl.results(res: %0) @@ -54,7 +54,7 @@ irdl.dialect @test_dialect3 { // ----- irdl.dialect @test_dialect4 { - // expected-error@+1 {{Error in symbol name `no_weird_symbol$`: Only numbers and lower-case characters allowed.}} + // expected-error@+1 {{name of operation "no_weird_symbol$" must contain only lowercase letters, digits and underscores}} irdl.operation @no_weird_symbol$ { %0 = irdl.any irdl.results(res: %0) @@ -66,7 +66,7 @@ irdl.dialect @test_dialect4 { irdl.dialect @test_dialect5 { irdl.operation @test_op { %0 = irdl.any - // expected-error@+1 {{Error in symbol name `_no_leading_underscore`: No leading or double underscores allowed.}} + // expected-error@+1 {{name of result "_no_leading_underscore" should not contain leading or double underscores}} irdl.results(_no_leading_underscore: %0) } } @@ -76,8 +76,8 @@ irdl.dialect @test_dialect5 { irdl.dialect @test_dialect6 { irdl.operation @test_op { %0 = irdl.any - // expected-error@+1 {{Error in symbol name `_no__double__underscores`: No leading or double underscores allowed.}} - irdl.results(_no__double__underscores: %0) + // expected-error@+1 {{name of result "no__double__underscores" should not contain leading or double underscores}} + irdl.results(no__double__underscores: %0) } } @@ -86,7 +86,7 @@ irdl.dialect @test_dialect6 { irdl.dialect @test_dialect7 { irdl.operation @test_op { %0 = irdl.any - // expected-error@+1 {{Error in symbol name `NoUpperCase`: Upper-case characters are not allowed.}} + // expected-error@+1 {{name of result "NoUpperCase" should not contain uppercase letters}} irdl.results(NoUpperCase: %0) } } diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index 7b3dbfbe2b949..07e07592f7873 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -75,7 +75,5 @@ irdl.dialect @test_irdl_to_cpp_8 { irdl.type @test_derived { // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} %0 = irdl.base "!builtin.integer" - } - + } } - diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 076a8027965c5..02ebfd5ee2192 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -27,6 +27,53 @@ #include "llvm/Support/ToolOutputFile.h" using namespace mlir; +/// Parses the memory buffer. If successfully, run a series of passes against +/// it and print the result. +static LogicalResult +processBuffer(llvm::ToolOutputFile *output, + std::unique_ptr ownedBuffer, + bool verifyDiagnostics, llvm::ThreadPoolInterface *threadPool) { + // Tell sourceMgr about this buffer, which is what the parser will pick up. + auto sourceMgr = std::make_shared(); + sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc()); + + DialectRegistry registry; + registry.insert(); + MLIRContext ctx(registry); + + ctx.printOpOnDiagnostic(!verifyDiagnostics); + + if (!verifyDiagnostics) { + ParserConfig parseConfig(&ctx); + OwningOpRef op = + parseSourceFileForTool(sourceMgr, parseConfig, true); + if (!op) + return failure(); + + auto moduleOp = llvm::cast(*op); + llvm::SmallVector dialects{ + moduleOp.getOps()}; + SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); + if (failed(irdl::translateIRDLDialectToCpp(dialects, output->os()))) + return failure(); + + output->keep(); + return success(); + } + + SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &ctx); + ParserConfig parseConfig(&ctx); + OwningOpRef op = + parseSourceFileForTool(sourceMgr, parseConfig, true); + if (!op) + return sourceMgrHandler.verify(); + + auto moduleOp = llvm::cast(*op); + llvm::SmallVector dialects{ + moduleOp.getOps()}; + ((void)irdl::translateIRDLDialectToCpp(dialects, output->os())); + return sourceMgrHandler.verify(); +} static LogicalResult translateIRDLToCpp(int argc, char **argv) { static llvm::cl::opt inputFilename( @@ -38,6 +85,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { llvm::cl::init("-")); bool verifyDiagnosticsFlag; + std::string splitInputFileFlag; static llvm::cl::opt verifyDiagnostics( @@ -46,6 +94,20 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { "expected-* lines on the corresponding line"), llvm::cl::location(verifyDiagnosticsFlag), llvm::cl::init(false)); + static llvm::cl::opt + splitInputFile( + "split-input-file", llvm::cl::ValueOptional, + llvm::cl::callback([&](const std::string &str) { + // Implicit value: use default marker if flag was used without + // value. + if (str.empty()) + splitInputFile.setValue(kDefaultSplitMarker); + }), + llvm::cl::desc("Split the input file into chunks using the given or " + "default marker and process each chunk independently"), + llvm::cl::location(splitInputFileFlag), llvm::cl::init("")); + llvm::InitLLVM y(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "mlir-irdl-to-cpp"); @@ -65,38 +127,17 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { return failure(); } - auto sourceMgr = std::make_shared(); - sourceMgr->AddNewSourceBuffer(std::move(input), SMLoc()); - - DialectRegistry registry; - registry.insert(); - MLIRContext ctx(registry); - ctx.printOpOnDiagnostic(true); - if (verifyDiagnostics) - ctx.printOpOnDiagnostic(false); - - ParserConfig parseConfig(&ctx); - OwningOpRef op = - parseSourceFileForTool(sourceMgr, parseConfig, true); - if (!op) - return failure(); - - auto moduleOp = llvm::cast(*op); - llvm::SmallVector dialects{ - moduleOp.getOps()}; - - if (!verifyDiagnostics) { - SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); - if (failed(irdl::translateIRDLDialectToCpp(dialects, output->os()))) - return failure(); - - output->keep(); - return success(); + auto chunkFn = [&](std::unique_ptr chunkBuffer, + raw_ostream &os) { + return processBuffer(output.get(), std::move(chunkBuffer), + verifyDiagnostics, nullptr); + }; + if (splitInputFileFlag.size()) { + return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), + "// -----", "// -----"); } - - SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &ctx); - ((void)irdl::translateIRDLDialectToCpp(dialects, output->os())); - return sourceMgrHandler.verify(); + return processBuffer(output.get(), std::move(input), verifyDiagnostics, + nullptr); } int main(int argc, char **argv) { From 8f7e93980736c95a5b2c2161639028b9a048ae24 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 25 Mar 2025 09:57:35 +0000 Subject: [PATCH 60/94] silence most failing tests --- mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 13 ++- mlir/test/Dialect/IRDL/invalid.irdl.mlir | 6 +- mlir/test/Dialect/IRDL/regions-ops.irdl.mlir | 12 +-- .../test_irdl_to_cpp_invalid_names.irdl.mlir | 80 +++++++-------- ...to_cpp_invalid_unsupported_types.irdl.mlir | 98 +++++++++---------- 5 files changed, 104 insertions(+), 105 deletions(-) diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index e56182aaac08e..748902d1c0627 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -84,19 +84,17 @@ static llvm::LogicalResult isSnakeCase(llvm::StringRef in, mlir::Operation *loc, if (elem == '_') { if (!allowUnderscore) return loc->emitError("name of ") - << label << " \"" << in - << "\" should not contain leading or double underscores"; + << label << " should not contain leading or double underscores"; } else { if (!isalnum(elem)) return loc->emitError("name of ") - << label << " \"" << in - << "\" must contain only lowercase letters, digits and " + << label + << " must contain only lowercase letters, digits and " "underscores"; if (llvm::isUpper(elem)) return loc->emitError("name of ") - << label << " \"" << in - << "\" should not contain uppercase letters"; + << label << " should not contain uppercase letters"; } allowUnderscore = elem != '_'; @@ -174,7 +172,8 @@ static LogicalResult verifyNames(Operation *op, StringRef kindName, DenseMap nameMap; for (auto [i, name] : llvm::enumerate(names)) { StringRef nameRef = llvm::cast(name).getValue(); - auto verifyNameRef = isSnakeCase(nameRef, op, kindName); + auto verifyNameRef = + isSnakeCase(nameRef, op, Twine(kindName) + " #" + Twine(i)); if (failed(verifyNameRef)) return verifyNameRef; diff --git a/mlir/test/Dialect/IRDL/invalid.irdl.mlir b/mlir/test/Dialect/IRDL/invalid.irdl.mlir index 1e66161b800df..8a7fffe1a9cbd 100644 --- a/mlir/test/Dialect/IRDL/invalid.irdl.mlir +++ b/mlir/test/Dialect/IRDL/invalid.irdl.mlir @@ -25,7 +25,7 @@ irdl.dialect @testd { irdl.dialect @testd { irdl.type @type { %0 = irdl.any - // expected-error@+1 {{name of parameter #0 must contain only letters, digits and underscores}} + // expected-error@+1 {{name of parameter #0 must contain only lowercase letters, digits and underscores}} irdl.parameters(test$test: %0) } } @@ -35,7 +35,7 @@ irdl.dialect @testd { irdl.dialect @testd { irdl.operation @op { %0 = irdl.any - // expected-error@+1 {{name of result #0 must contain only letters, digits and underscores}} + // expected-error@+1 {{name of result #0 must contain only lowercase letters, digits and underscores}} irdl.results(test$test: %0) } } @@ -45,7 +45,7 @@ irdl.dialect @testd { irdl.dialect @testd { irdl.operation @op { %0 = irdl.any - // expected-error@+1 {{name of operand #0 must contain only letters, digits and underscores}} + // expected-error@+1 {{name of operand #0 must contain only lowercase letters, digits and underscores}} irdl.operands(test$test: %0) } } diff --git a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir index 7c2efc6c96e41..e5f884c99e5f4 100644 --- a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir +++ b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir @@ -1,6 +1,6 @@ // RUN: mlir-opt %s -verify-diagnostics -split-input-file -irdl.dialect @testRegionOpNegativeNumber { +irdl.dialect @test_region_op_negative_number { irdl.operation @op { // expected-error @below {{'irdl.region' op the number of blocks is expected to be >= 1 but got -42}} %r1 = irdl.region with size -42 @@ -9,7 +9,7 @@ irdl.dialect @testRegionOpNegativeNumber { // ----- -irdl.dialect @testRegionsOpMissingName { +irdl.dialect @test_regions_op_missing_name { irdl.operation @op { %r1 = irdl.region // expected-error @below {{expected valid keyword}} @@ -19,17 +19,17 @@ irdl.dialect @testRegionsOpMissingName { // ----- -irdl.dialect @testRegionsOpWrongName { +irdl.dialect @test_regions_op_wrong_name { irdl.operation @op { %r1 = irdl.region - // expected-error @below {{name of region #0 must contain only letters, digits and underscores}} + // expected-error @below {{name of region #0 must contain only lowercase letters, digits and underscores}} irdl.regions(test$test: %r1) } } // ----- -irdl.dialect @testRegionsDuplicateName { +irdl.dialect @test_regions_duplicate_name { irdl.operation @op { %r1 = irdl.region // expected-error @below {{name of region #2 is a duplicate of the name of region #0}} @@ -39,7 +39,7 @@ irdl.dialect @testRegionsDuplicateName { // ----- -irdl.dialect @testRegionsOpWrongOperation { +irdl.dialect @test_regions_op_wrong_operation { irdl.operation @op { // expected-note @below {{prior use here}} %r1 = irdl.any diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir index 27d85f5456c14..e2d2be52fc3db 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir @@ -1,50 +1,50 @@ // RUN: mlir-irdl-to-cpp %s --verify-diagnostics --split-input-file -// expected-error@+1 {{name of dialect "_no_leading_underscore" should not contain leading or double underscores}} +// expected-error@+1 {{name of dialect should not contain leading or double underscores}} irdl.dialect @_no_leading_underscore { } // ----- -// expected-error@+1 {{name of dialect "no__double__underscores" should not contain leading or double underscores}} +// expected-error@+1 {{name of dialect should not contain leading or double underscores}} irdl.dialect @no__double__underscores { } // ----- -// expected-error@+1 {{name of dialect "NoUpperCase" should not contain uppercase letters}} +// expected-error@+1 {{name of dialect should not contain uppercase letters}} irdl.dialect @NoUpperCase { } // ----- -// expected-error@+1 {{name of dialect "no_weird_symbol$" must contain only lowercase letters, digits and underscores}} +// expected-error@+1 {{name of dialect must contain only lowercase letters, digits and underscores}} irdl.dialect @no_weird_symbol$ { } // ----- irdl.dialect @test_dialect { - // expected-error@+1 {{name of operation "_no_leading_underscore" should not contain leading or double underscores}} - irdl.operation @_no_leading_underscore { - %0 = irdl.any - irdl.results(res: %0) - } + // expected-error@+1 {{name of operation should not contain leading or double underscores}} + irdl.operation @_no_leading_underscore { + %0 = irdl.any + irdl.results(res: %0) + } } // ----- irdl.dialect @test_dialect { - // expected-error@+1 {{name of operation "no__double__underscores" should not contain leading or double underscores}} - irdl.operation @no__double__underscores { - %0 = irdl.any - irdl.results(res: %0) - } + // expected-error@+1 {{name of operation should not contain leading or double underscores}} + irdl.operation @no__double__underscores { + %0 = irdl.any + irdl.results(res: %0) + } } // ----- -irdl.dialect @test_dialect3 { - // expected-error@+1 {{name of operation "NoUpperCase" should not contain uppercase letters}} +irdl.dialect @test_dialect { + // expected-error@+1 {{name of operation should not contain uppercase letters}} irdl.operation @NoUpperCase { %0 = irdl.any irdl.results(res: %0) @@ -53,42 +53,42 @@ irdl.dialect @test_dialect3 { // ----- -irdl.dialect @test_dialect4 { - // expected-error@+1 {{name of operation "no_weird_symbol$" must contain only lowercase letters, digits and underscores}} - irdl.operation @no_weird_symbol$ { - %0 = irdl.any - irdl.results(res: %0) - } +irdl.dialect @test_dialect { + // expected-error@+1 {{name of operation must contain only lowercase letters, digits and underscores}} + irdl.operation @no_weird_symbol$ { + %0 = irdl.any + irdl.results(res: %0) + } } // ----- -irdl.dialect @test_dialect5 { - irdl.operation @test_op { - %0 = irdl.any - // expected-error@+1 {{name of result "_no_leading_underscore" should not contain leading or double underscores}} - irdl.results(_no_leading_underscore: %0) - } +irdl.dialect @test_dialect { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{name of result #0 should not contain leading or double underscores}} + irdl.results(_no_leading_underscore: %0) + } } // ----- -irdl.dialect @test_dialect6 { - irdl.operation @test_op { - %0 = irdl.any - // expected-error@+1 {{name of result "no__double__underscores" should not contain leading or double underscores}} - irdl.results(no__double__underscores: %0) - } +irdl.dialect @test_dialect { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{name of result #0 should not contain leading or double underscores}} + irdl.results(no__double__underscores: %0) + } } // ----- -irdl.dialect @test_dialect7 { - irdl.operation @test_op { - %0 = irdl.any - // expected-error@+1 {{name of result "NoUpperCase" should not contain uppercase letters}} - irdl.results(NoUpperCase: %0) - } +irdl.dialect @test_dialect { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{name of result #0 should not contain uppercase letters}} + irdl.results(NoUpperCase: %0) + } } // ----- diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index 07e07592f7873..7a5fe7cd435e1 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -1,79 +1,79 @@ -// RUN: mlir-irdl-to-cpp %s --verify-diagnostics +// RUN: mlir-irdl-to-cpp %s --verify-diagnostics --split-input-file irdl.dialect @test_irdl_to_cpp { - irdl.operation @results_no_any_of { - %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} - %1 = irdl.any_of(%0, %0) - irdl.results(res: %1) - } + irdl.operation @results_no_any_of { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + %1 = irdl.any_of(%0, %0) + irdl.results(res: %1) + } } // ----- -irdl.dialect @test_irdl_to_cpp_2 { - irdl.operation @operands_no_any_of { - %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} - %1 = irdl.all_of(%0, %0) - irdl.operands(test: %1) - irdl.results(res: %0) - } +irdl.dialect @test_irdl_to_cpp { + irdl.operation @operands_no_any_of { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + %1 = irdl.all_of(%0, %0) + irdl.operands(test: %1) + irdl.results(res: %0) + } } // ----- -irdl.dialect @test_irdl_to_cpp_3 { - // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} - irdl.attribute @no_attrs +irdl.dialect @test_irdl_to_cpp { + // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + irdl.attribute @no_attrs } // ----- -irdl.dialect @test_irdl_to_cpp_4 { - irdl.operation @test_op { - %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} - irdl.attributes { - "attr" = %0 - } +irdl.dialect @test_irdl_to_cpp { + irdl.operation @test_op { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + irdl.attributes { + "attr" = %0 } + } } // ----- -irdl.dialect @test_irdl_to_cpp_5 { - irdl.type @ty { - %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support type parameters.}} - irdl.parameters(ty: %0) - } +irdl.dialect @test_irdl_to_cpp { + irdl.type @ty { + %0 = irdl.any + // expected-error@+1 {{IRDL C++ translation does not yet support type parameters.}} + irdl.parameters(ty: %0) + } } // ----- -irdl.dialect @test_irdl_to_cpp_6 { - irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} - %0 = irdl.region() - irdl.regions(reg: %0) - } - +irdl.dialect @test_irdl_to_cpp { + irdl.operation @test_op { + // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + %0 = irdl.region() + irdl.regions(reg: %0) + } + } // ----- -irdl.dialect @test_irdl_to_cpp_7 { - irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} - irdl.regions() - } - +irdl.dialect @test_irdl_to_cpp { + irdl.operation @test_op { + // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + irdl.regions() + } + } // ----- -irdl.dialect @test_irdl_to_cpp_8 { - irdl.type @test_derived { - // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} - %0 = irdl.base "!builtin.integer" - } +irdl.dialect @test_irdl_to_cpp { + irdl.type @test_derived { + // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} + %0 = irdl.base "!builtin.integer" + } } From 764d638df40e5912e1b31be01b99d1574b16a950 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 25 Mar 2025 10:36:52 +0000 Subject: [PATCH 61/94] allow types and attribs to be prefixed with ! and # --- mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td | 2 ++ mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td index 2e640de2c4965..40b13167a973d 100644 --- a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td +++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td @@ -127,6 +127,8 @@ def IRDL_AttributeOp : IRDL_Op<"attribute", let regions = (region SizedRegion<1>:$body); let assemblyFormat = "$sym_name attr-dict-with-keyword custom($body)"; + + let hasVerifier = 1; } def IRDL_ParametersOp : IRDL_Op<"parameters", diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index 748902d1c0627..e586ca3c4be47 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -106,18 +106,28 @@ static llvm::LogicalResult isSnakeCase(llvm::StringRef in, mlir::Operation *loc, LogicalResult DialectOp::verify() { if (!Dialect::isValidNamespace(getName())) return emitOpError("invalid dialect name"); - if (failed(isSnakeCase(getName(), getOperation(), "dialect"))) + if (failed(isSnakeCase(getSymName(), getOperation(), "dialect"))) return failure(); return success(); } LogicalResult OperationOp::verify() { - return isSnakeCase(getName(), getOperation(), "operation"); + return isSnakeCase(getSymName(), getOperation(), "operation"); } LogicalResult TypeOp::verify() { - return isSnakeCase(getName(), getOperation(), "type"); + auto symName = getSymName(); + if (symName.front() == '!') + symName = symName.substr(1); + return isSnakeCase(symName, getOperation(), "type"); +} + +LogicalResult AttributeOp::verify() { + auto symName = getSymName(); + if (symName.front() == '#') + symName = symName.substr(1); + return isSnakeCase(symName, getOperation(), "attribute"); } LogicalResult OperationOp::verifyRegions() { From dfbb91910c417ced4e08734bd7df5b4811b2d0db Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Wed, 26 Mar 2025 16:48:22 +0000 Subject: [PATCH 62/94] clean up mlir-irdl-to-cpp --- .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 02ebfd5ee2192..e34b2d6a73279 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -30,7 +30,7 @@ using namespace mlir; /// Parses the memory buffer. If successfully, run a series of passes against /// it and print the result. static LogicalResult -processBuffer(llvm::ToolOutputFile *output, +processBuffer(llvm::raw_ostream &os, std::unique_ptr ownedBuffer, bool verifyDiagnostics, llvm::ThreadPoolInterface *threadPool) { // Tell sourceMgr about this buffer, which is what the parser will pick up. @@ -43,36 +43,35 @@ processBuffer(llvm::ToolOutputFile *output, ctx.printOpOnDiagnostic(!verifyDiagnostics); - if (!verifyDiagnostics) { - ParserConfig parseConfig(&ctx); - OwningOpRef op = - parseSourceFileForTool(sourceMgr, parseConfig, true); - if (!op) - return failure(); + std::variant + sourceMgrHandler; + if (verifyDiagnostics) + sourceMgrHandler.emplace(*sourceMgr, + &ctx); + else + sourceMgrHandler.emplace(*sourceMgr, &ctx); + auto *sourceMgrVerifierHandler = + std::get_if(&sourceMgrHandler); - auto moduleOp = llvm::cast(*op); - llvm::SmallVector dialects{ - moduleOp.getOps()}; - SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &ctx); - if (failed(irdl::translateIRDLDialectToCpp(dialects, output->os()))) - return failure(); - - output->keep(); - return success(); - } - - SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &ctx); ParserConfig parseConfig(&ctx); OwningOpRef op = parseSourceFileForTool(sourceMgr, parseConfig, true); if (!op) - return sourceMgrHandler.verify(); + return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() + : failure(); auto moduleOp = llvm::cast(*op); llvm::SmallVector dialects{ - moduleOp.getOps()}; - ((void)irdl::translateIRDLDialectToCpp(dialects, output->os())); - return sourceMgrHandler.verify(); + moduleOp.getOps(), + }; + + if (failed(irdl::translateIRDLDialectToCpp(dialects, os))) + return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() + : failure(); + + return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() + : success(); } static LogicalResult translateIRDLToCpp(int argc, char **argv) { @@ -122,6 +121,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { std::unique_ptr output = openOutputFile(outputFilename, &errorMessage); + if (!output) { llvm::errs() << errorMessage << "\n"; return failure(); @@ -129,15 +129,21 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { auto chunkFn = [&](std::unique_ptr chunkBuffer, raw_ostream &os) { - return processBuffer(output.get(), std::move(chunkBuffer), + return processBuffer(output->os(), std::move(chunkBuffer), verifyDiagnostics, nullptr); }; + if (splitInputFileFlag.size()) { return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), - "// -----", "// -----"); + splitInputFileFlag, splitInputFileFlag); } - return processBuffer(output.get(), std::move(input), verifyDiagnostics, - nullptr); + + if (failed(chunkFn(std::move(input), output->os()))) + return failure(); + + if (!verifyDiagnosticsFlag) + output->keep(); + return success(); } int main(int argc, char **argv) { From 3638c9bc668661035c41d7b0a028e5280ed24e6f Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 31 Mar 2025 15:00:00 +0000 Subject: [PATCH 63/94] fixed PR changes --- mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 7 +- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 91 ++++++------------------- 2 files changed, 24 insertions(+), 74 deletions(-) diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index e586ca3c4be47..38a9a8e17fb40 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -182,10 +182,9 @@ static LogicalResult verifyNames(Operation *op, StringRef kindName, DenseMap nameMap; for (auto [i, name] : llvm::enumerate(names)) { StringRef nameRef = llvm::cast(name).getValue(); - auto verifyNameRef = - isSnakeCase(nameRef, op, Twine(kindName) + " #" + Twine(i)); - if (failed(verifyNameRef)) - return verifyNameRef; + + if (failed(isSnakeCase(nameRef, op, Twine(kindName) + " #" + Twine(i)))) + return failure(); if (nameMap.contains(nameRef)) return op->emitOpError() << "name of " << kindName << " #" << i diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 1890f2c374e85..852b0a3ad1f4e 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -61,60 +61,14 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } -static llvm::LogicalResult isSnakeCase(llvm::StringRef in, - mlir::Operation *loc) { - bool allowUnderscore = false; - for (auto &elem : in) { - if (elem == '_') { - if (!allowUnderscore) - return loc->emitError( - llvm::formatv("Error in symbol name `{}`: No leading or double " - "underscores allowed.", - in)); - } else { - if (!isalnum(elem)) - return loc->emitError( - llvm::formatv("Error in symbol name `{}`: Only numbers and " - "lower-case characters allowed.", - in)); - - if (llvm::isUpper(elem)) - return loc->emitError(llvm::formatv( - "Error in symbol name `{}`: Upper-case characters are not allowed.", - in)); - } - - allowUnderscore = elem != '_'; - } - - return success(); -} - -static std::string snakeToCamel(llvm::StringRef in, bool capitalize = false) { - std::string output; - output.reserve(in.size()); - - for (char c : in) { - if (c == '_') { - capitalize = true; - } else { - output += capitalize ? toupper(c) : c; - capitalize = false; - } - } - return output; -} - -static std::string snakeToPascal(llvm::StringRef in) { - return snakeToCamel(in, /*capitalize=*/true); -} - static std::string typeToCppName(irdl::TypeOp type) { - return llvm::formatv("{0}Type", snakeToPascal(type.getSymName())); + return llvm::formatv("{0}Type", + convertToCamelFromSnakeCase(type.getSymName(), true)); } static std::string opToCppName(irdl::OperationOp op) { - return llvm::formatv("{0}Op", snakeToPascal(op.getSymName())); + return llvm::formatv("{0}Op", + convertToCamelFromSnakeCase(op.getSymName(), true)); } static TypeStrings getStrings(irdl::TypeOp type) { @@ -229,13 +183,15 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto res_getters = std::string{}; for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { - const auto &op = snakeToPascal(opStrings.opOperandNames[i]); + const auto op = + llvm::convertToCamelFromSnakeCase(opStrings.opOperandNames[i], true); op_getters += llvm::formatv( "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n ", op, i); } for (size_t i = 0; i < opStrings.opResultNames.size(); ++i) { - const auto &op = snakeToPascal(opStrings.opResultNames[i]); + const auto op = + llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true); res_getters += llvm::formatv( R"(::mlir::TypedValue<::mlir::Type> get{0}() { return ::llvm::cast<::mlir::TypedValue<::mlir::Type>>(getODSResults({1}).front()); } )", @@ -250,16 +206,18 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, auto resultParams = llvm::join(llvm::map_range(opStrings.opResultNames, [](StringRef name) -> std::string { - return llvm::formatv("::mlir::Type {0}, ", - snakeToCamel(name)); + return llvm::formatv( + "::mlir::Type {0}, ", + llvm::convertToCamelFromSnakeCase(name)); }), ""); auto operandParams = llvm::join(llvm::map_range(opStrings.opOperandNames, [](StringRef name) -> std::string { - return llvm::formatv("::mlir::Value {0}, ", - snakeToCamel(name)); + return llvm::formatv( + "::mlir::Value {0}, ", + llvm::convertToCamelFromSnakeCase(name)); }), ""); @@ -502,9 +460,6 @@ void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, } static LogicalResult verifySupported(irdl::DialectOp dialect) { - if (failed(isSnakeCase(dialect.getSymName(), dialect))) - return failure(); - LogicalResult res = success(); dialect.walk([&](mlir::Operation *op) { res = @@ -580,8 +535,7 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, StringRef dialectName = dialect.getSymName(); if (failed(verifySupported(dialect))) { - result = failure(); - continue; + return failure(); } llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, @@ -598,7 +552,8 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, namespacePathStream << "::" << pathElement; } - std::string cppShortName = snakeToPascal(dialectName); + std::string cppShortName = + llvm::convertToCamelFromSnakeCase(dialectName, true); std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName); std::string cppName = llvm::formatv("{0}Dialect", cppShortName); @@ -614,17 +569,13 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, output << headerTemplateText; if (failed(generateInclude(dialect, output, dialectStrings))) { - dialect->emitError("Error in Dialect " + dialectName + - " while generating headers"); - result = failure(); - continue; + return dialect->emitError("Error in Dialect " + dialectName + + " while generating headers"); } if (failed(generateLib(dialect, output, dialectStrings))) { - dialect->emitError("Error in Dialect " + dialectName + - " while generating library"); - result = failure(); - continue; + return dialect->emitError("Error in Dialect " + dialectName + + " while generating library"); } } From a1f308eb852b9c38c6894409c6992e5415f396d5 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 31 Mar 2025 15:02:46 +0000 Subject: [PATCH 64/94] renamed name checker --- mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index 38a9a8e17fb40..bcc9f0b109ac2 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -74,7 +74,7 @@ static void printSingleBlockRegion(OpAsmPrinter &p, Operation *op, if (!region.getBlocks().front().empty()) p.printRegion(region); } -static llvm::LogicalResult isSnakeCase(llvm::StringRef in, mlir::Operation *loc, +static llvm::LogicalResult isValidName(llvm::StringRef in, mlir::Operation *loc, const Twine &label) { if (in.empty()) return loc->emitError("name of ") << label << " is empty"; @@ -106,28 +106,28 @@ static llvm::LogicalResult isSnakeCase(llvm::StringRef in, mlir::Operation *loc, LogicalResult DialectOp::verify() { if (!Dialect::isValidNamespace(getName())) return emitOpError("invalid dialect name"); - if (failed(isSnakeCase(getSymName(), getOperation(), "dialect"))) + if (failed(isValidName(getSymName(), getOperation(), "dialect"))) return failure(); return success(); } LogicalResult OperationOp::verify() { - return isSnakeCase(getSymName(), getOperation(), "operation"); + return isValidName(getSymName(), getOperation(), "operation"); } LogicalResult TypeOp::verify() { auto symName = getSymName(); if (symName.front() == '!') symName = symName.substr(1); - return isSnakeCase(symName, getOperation(), "type"); + return isValidName(symName, getOperation(), "type"); } LogicalResult AttributeOp::verify() { auto symName = getSymName(); if (symName.front() == '#') symName = symName.substr(1); - return isSnakeCase(symName, getOperation(), "attribute"); + return isValidName(symName, getOperation(), "attribute"); } LogicalResult OperationOp::verifyRegions() { @@ -183,7 +183,7 @@ static LogicalResult verifyNames(Operation *op, StringRef kindName, for (auto [i, name] : llvm::enumerate(names)) { StringRef nameRef = llvm::cast(name).getValue(); - if (failed(isSnakeCase(nameRef, op, Twine(kindName) + " #" + Twine(i)))) + if (failed(isValidName(nameRef, op, Twine(kindName) + " #" + Twine(i)))) return failure(); if (nameMap.contains(nameRef)) From db38f4e65c1cd195992c10508a74e21b21fff5c6 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 31 Mar 2025 15:19:18 +0000 Subject: [PATCH 65/94] invert verifysupport check --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 61 ++++--------------- ...to_cpp_invalid_unsupported_types.irdl.mlir | 16 ++--- 2 files changed, 21 insertions(+), 56 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 852b0a3ad1f4e..9a1ab512042ce 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -464,54 +464,19 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { dialect.walk([&](mlir::Operation *op) { res = llvm::TypeSwitch(op) - .Case([](irdl::AttributeOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support attributes."); - }) - .Case( - [](irdl::AttributesOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support attributes."); - }) - .Case([](irdl::AnyOfOp op) -> LogicalResult { - return op.emitError("IRDL C++ translation only supports irdl.any " - "constraint for types"); - }) - .Case([](irdl::AllOfOp op) -> LogicalResult { - return op.emitError("IRDL C++ translation only supports irdl.any " - "constraint for types"); - }) - .Case([](irdl::BaseOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support base types."); - }) - .Case([](irdl::ParametersOp op) - -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support type parameters."); - }) - .Case( - [](irdl::ParametricOp op) -> LogicalResult { - return op.emitError("IRDL C++ translation does not yet " - "support parametric operations."); - }) - .Case([](irdl::RegionOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support regions."); - }) - .Case([](irdl::RegionsOp op) -> LogicalResult { - return op.emitError( - "IRDL C++ translation does not yet support regions."); - }) - .Case([](irdl::IsOp op) -> LogicalResult { - return op.emitError("IRDL C++ translation only supports irdl.any " - "constraint for types"); - }) - .Case([](irdl::CPredOp op) -> LogicalResult { - return op.emitError("IRDL C++ translation only supports irdl.any " - "constraint for types"); - }) - .Default(success()); + .Case(([](irdl::DialectOp) { return success(); })) + .Case( + ([](irdl::OperationOp) { return success(); })) + .Case(([](irdl::TypeOp) { return success(); })) + .Case( + ([](irdl::OperandsOp) { return success(); })) + .Case(([](irdl::ResultsOp) { return success(); })) + .Case(([](irdl::AnyOp) { return success(); })) + .Default([](mlir::Operation *op) -> LogicalResult { + return op->emitError("IRDL C++ translation does not yet support " + "translation of ") + << op->getName() << "operation"; + }); if (failed(res)) return WalkResult::interrupt(); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index 7a5fe7cd435e1..3e42a09537871 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -2,7 +2,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.operation @results_no_any_of { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.any_ofoperation}} %1 = irdl.any_of(%0, %0) irdl.results(res: %1) } @@ -12,7 +12,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @operands_no_any_of { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation only supports irdl.any constraint for types}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.all_ofoperation}} %1 = irdl.all_of(%0, %0) irdl.operands(test: %1) irdl.results(res: %0) @@ -22,7 +22,7 @@ irdl.dialect @test_irdl_to_cpp { // ----- irdl.dialect @test_irdl_to_cpp { - // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attributeoperation}} irdl.attribute @no_attrs } @@ -31,7 +31,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support attributes.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attributesoperation}} irdl.attributes { "attr" = %0 } @@ -43,7 +43,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.type @ty { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support type parameters.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.parametersoperation}} irdl.parameters(ty: %0) } } @@ -52,7 +52,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.regionoperation}} %0 = irdl.region() irdl.regions(reg: %0) } @@ -63,7 +63,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support regions.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.regionsoperation}} irdl.regions() } @@ -73,7 +73,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.type @test_derived { - // expected-error@+1 {{IRDL C++ translation does not yet support base types.}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.baseoperation}} %0 = irdl.base "!builtin.integer" } } From 1295496bf64fb7f4cb83c92dfd5803aa22f02870 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 31 Mar 2025 15:32:48 +0000 Subject: [PATCH 66/94] attempt to clean up main.cpp --- .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index e34b2d6a73279..01721b86a55b3 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -43,23 +43,30 @@ processBuffer(llvm::raw_ostream &os, ctx.printOpOnDiagnostic(!verifyDiagnostics); - std::variant - sourceMgrHandler; - if (verifyDiagnostics) - sourceMgrHandler.emplace(*sourceMgr, - &ctx); - else - sourceMgrHandler.emplace(*sourceMgr, &ctx); - auto *sourceMgrVerifierHandler = - std::get_if(&sourceMgrHandler); + using SourceDiagnosticHandlerVariant = + std::variant; + + auto sourceMgrHandler = + verifyDiagnostics + ? SourceDiagnosticHandlerVariant( + std::in_place_type_t{}, + *sourceMgr, &ctx) + : SourceDiagnosticHandlerVariant( + std::in_place_type_t{}, *sourceMgr, + &ctx); + + const auto verifyOr = + [verifier = std::get_if( + &sourceMgrHandler)](LogicalResult res) -> LogicalResult { + return verifier ? verifier->verify() : res; + }; ParserConfig parseConfig(&ctx); OwningOpRef op = parseSourceFileForTool(sourceMgr, parseConfig, true); if (!op) - return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() - : failure(); + return verifyOr(failure()); auto moduleOp = llvm::cast(*op); llvm::SmallVector dialects{ @@ -67,11 +74,9 @@ processBuffer(llvm::raw_ostream &os, }; if (failed(irdl::translateIRDLDialectToCpp(dialects, os))) - return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() - : failure(); + return verifyOr(failure()); - return sourceMgrVerifierHandler ? sourceMgrVerifierHandler->verify() - : success(); + return verifyOr(success()); } static LogicalResult translateIRDLToCpp(int argc, char **argv) { @@ -85,27 +90,23 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { bool verifyDiagnosticsFlag; std::string splitInputFileFlag; - static llvm::cl::opt - verifyDiagnostics( - "verify-diagnostics", - llvm::cl::desc("Check that emitted diagnostics match " - "expected-* lines on the corresponding line"), - llvm::cl::location(verifyDiagnosticsFlag), llvm::cl::init(false)); - - static llvm::cl::opt - splitInputFile( - "split-input-file", llvm::cl::ValueOptional, - llvm::cl::callback([&](const std::string &str) { - // Implicit value: use default marker if flag was used without - // value. - if (str.empty()) - splitInputFile.setValue(kDefaultSplitMarker); - }), - llvm::cl::desc("Split the input file into chunks using the given or " - "default marker and process each chunk independently"), - llvm::cl::location(splitInputFileFlag), llvm::cl::init("")); + static llvm::cl::opt verifyDiagnostics( + "verify-diagnostics", + llvm::cl::desc("Check that emitted diagnostics match " + "expected-* lines on the corresponding line"), + llvm::cl::location(verifyDiagnosticsFlag), llvm::cl::init(false)); + + static llvm::cl::opt splitInputFile( + "split-input-file", llvm::cl::ValueOptional, + llvm::cl::callback([&](const std::string &str) { + // Implicit value: use default marker if flag was used without + // value. + if (str.empty()) + splitInputFile.setValue(kDefaultSplitMarker); + }), + llvm::cl::desc("Split the input file into chunks using the given or " + "default marker and process each chunk independently"), + llvm::cl::location(splitInputFileFlag), llvm::cl::init("")); llvm::InitLLVM y(argc, argv); @@ -133,16 +134,16 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { verifyDiagnostics, nullptr); }; - if (splitInputFileFlag.size()) { + if (splitInputFileFlag.size()) return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), splitInputFileFlag, splitInputFileFlag); - } if (failed(chunkFn(std::move(input), output->os()))) return failure(); if (!verifyDiagnosticsFlag) output->keep(); + return success(); } From b35f796240a960286a3b3c18fa433c93fe9e8d5e Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 31 Mar 2025 16:07:38 +0000 Subject: [PATCH 67/94] removed name with underscore --- mlir/test/tblgen-to-irdl/TestDialect.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/test/tblgen-to-irdl/TestDialect.td b/mlir/test/tblgen-to-irdl/TestDialect.td index 913b9b1b759e2..4ab1750e30fb4 100644 --- a/mlir/test/tblgen-to-irdl/TestDialect.td +++ b/mlir/test/tblgen-to-irdl/TestDialect.td @@ -97,7 +97,7 @@ def Test_Integers : Test_Op<"integers"> { // Check that IRDL names are properly generated when needed. def Test_NamesOp : Test_Op<"names"> { let arguments = (ins I32:$a, - I32:$_hello, + I32:$hello, I32:$unnamed0, I32); let regions = (region AnyRegion:$unnamed1); @@ -110,7 +110,7 @@ def Test_NamesOp : Test_Op<"names"> { // CHECK-NEXT: %[[v3:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v4:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[reg:[^ ]*]] = irdl.region -// CHECK-NEXT: irdl.operands(a: %[[v0]], _hello: %[[v1]], unnamed0: %[[v2]], unnamed3: %[[v3]]) +// CHECK-NEXT: irdl.operands(a: %[[v0]], hello: %[[v1]], unnamed0: %[[v2]], unnamed3: %[[v3]]) // CHECK-NEXT: irdl.results(unnamed2: %[[v4]]) // CHECK-NEXT: irdl.regions(unnamed1: %[[reg]]) // CHECK-NEXT: } From 7c52b16f55bca033968fc8a8ae0349ef68c5f299 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 1 Apr 2025 19:40:09 +0000 Subject: [PATCH 68/94] simple cleanup --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 2 +- .../IRDLToCpp/Templates/PerOperationDecl.txt | 4 ---- .../IRDLToCpp/Templates/PerOperationDef.txt | 19 ------------------- .../Target/IRDLToCpp/Templates/TypeDef.txt | 15 +-------------- .../IRDLToCpp/Templates/TypeHeaderDecl.txt | 9 --------- .../IRDLToCpp/Templates/TypeHeaderDef.txt | 8 -------- .../lib/Dialect/TestIRDLToCpp/test.testd.mlir | 3 ++- .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 17 ----------------- 8 files changed, 4 insertions(+), 73 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 9a1ab512042ce..9cd495b55d0c3 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -193,7 +193,7 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true); res_getters += llvm::formatv( - R"(::mlir::TypedValue<::mlir::Type> get{0}() { return ::llvm::cast<::mlir::TypedValue<::mlir::Type>>(getODSResults({1}).front()); } + R"(::mlir::Value get{0}() { return ::llvm::cast<::mlir::Value>(getODSResults({1}).front()); } )", op, i); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index a75d87d5b45fc..68733ee35ae2c 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -134,10 +134,6 @@ public: __OP_BUILD_DECLS__ static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); - - ::llvm::LogicalResult verifyInvariantsImpl(); - ::llvm::LogicalResult verifyInvariants(); -public: }; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index 32a114e053d46..ac80d382d4ceb 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -1,14 +1,3 @@ -/* -0: Operation CppName -1: Operand count -2: Result count -3: Build definitions - -4: open namespace -5: close namespace -6: namespace path -*/ - R"( //===----------------------------------------------------------------------===// @@ -17,14 +6,6 @@ R"( __NAMESPACE_OPEN__ -::llvm::LogicalResult __OP_CPP_NAME__::verifyInvariantsImpl() { - return ::mlir::success(); -} - -::llvm::LogicalResult __OP_CPP_NAME__::verifyInvariants() { - return verifyInvariantsImpl(); -} - __OP_BUILD_DEFS__ void __OP_CPP_NAME__::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) { diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index 570226a40b7d4..e78182c63995d 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -1,17 +1,5 @@ -/* -{0}: TypeDef list -{1}: TypeParser function -{2}: TypePrinter function -{3}: Dialect CppName -{4}: TypeID Defines -{5}: Namespace open -{6}: Namespace close -*/ - R"( - - __TYPE_DEFINES__ __NAMESPACE_OPEN__ @@ -36,8 +24,7 @@ __TYPE_PRINTER__ /// Print a type registered to this dialect. void __DIALECT_CPP_NAME__::printType(::mlir::Type type, ::mlir::DialectAsmPrinter &printer) const { - if (::mlir::succeeded(generatedTypePrinter(type, printer))) - return; + ((void) generatedTypePrinter(type, printer)); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index e4e2ead7abe22..ec54be7352715 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -1,12 +1,3 @@ -/* -{0}: Dialect BaseTypeName - -{1}: Open namespace -{2}: Close namespace -{3}: Namespace path -*/ - - R"( __NAMESPACE_OPEN__ diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt index c3e341fff2085..be5ba2f390fce 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDef.txt @@ -1,11 +1,3 @@ -/* -{0}: Dialect BaseTypeName -{1}: Dialect CppName - -{2}: Namespace open -{3}: Namespace close -*/ - R"( __NAMESPACE_OPEN__ diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir index 34b5632daa5ab..7d7bae72059f5 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir @@ -1,5 +1,6 @@ // RUN: mlir-opt %s | FileCheck %s -// CHECK: module { +// CHECK: module { +// CHECK-LABEL: [[v1: *]] = "test_irdl_to_cpp.bar" module { %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index 6cca614264ba1..ee80c8929754d 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -1,35 +1,18 @@ // RUN: mlir-irdl-to-cpp %s -// CHECK-LABEL: irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { - // CHECK: irdl.type @foo irdl.type @foo - // CHECK: irdl.type @bar { - // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.results(res: %[[v0]]) - // CHECK: } irdl.operation @bar { %0 = irdl.any irdl.results(res: %0) } - - // CHECK: irdl.type @beef { - // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) - // CHECK: irdl.results(res: %[[v0]]) - // CHECK: } irdl.operation @beef { %0 = irdl.any irdl.operands(lhs: %0, rhs: %0) irdl.results(res: %0) } - // CHECK: irdl.type @hash { - // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.operands(lhs: %[[v0]], rhs: %[[v0]]) - // CHECK: irdl.results(res: %[[v0]]) - // CHECK: } irdl.operation @hash { %0 = irdl.any irdl.operands(lhs: %0, rhs: %0) From 81a15301f4b0ff19d64674f6c127802491c2dfcf Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 1 Apr 2025 20:08:15 +0000 Subject: [PATCH 69/94] remaining fixes --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 242 +++++++++--------- .../IRDLToCpp/Templates/PerOperationDecl.txt | 22 +- .../lib/Dialect/TestIRDLToCpp/test.testd.mlir | 2 +- 3 files changed, 139 insertions(+), 127 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 9cd495b55d0c3..d7b69e060023f 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -49,8 +49,8 @@ struct TypeStrings { struct OpStrings { StringRef opName; std::string opCppName; - llvm::SmallVector opResultNames; - llvm::SmallVector opOperandNames; + SmallVector opResultNames; + SmallVector opOperandNames; }; static std::string joinNameList(llvm::ArrayRef names) { @@ -92,14 +92,14 @@ static OpStrings getStrings(irdl::OperationOp op) { strings.opCppName = opToCppName(op); if (operandOp) { - strings.opOperandNames = llvm::SmallVector( + strings.opOperandNames = SmallVector( llvm::map_range(operandOp->getNames(), [](Attribute attr) { return llvm::formatv("{0}", cast(attr)); })); } if (resultOp) { - strings.opResultNames = llvm::SmallVector( + strings.opResultNames = SmallVector( llvm::map_range(resultOp->getNames(), [](Attribute attr) { return llvm::formatv("{0}", cast(attr)); })); @@ -139,20 +139,19 @@ static void fillDict(irdl::detail::dictionary &dict, dict["NAMESPACE_PATH"] = strings.namespacePath; } -static LogicalResult -generateTypedefList(irdl::DialectOp &dialect, - llvm::SmallVector &typeNames) { +static LogicalResult generateTypedefList(irdl::DialectOp &dialect, + SmallVector &typeNames) { auto typeOps = dialect.getOps(); auto range = llvm::map_range(typeOps, typeToCppName); - typeNames = llvm::SmallVector(range); + typeNames = SmallVector(range); return success(); } static LogicalResult generateOpList(irdl::DialectOp &dialect, - llvm::SmallVector &opNames) { + SmallVector &opNames) { auto operationOps = dialect.getOps(); auto range = llvm::map_range(operationOps, opToCppName); - opNames = llvm::SmallVector(range); + opNames = SmallVector(range); return success(); } @@ -185,15 +184,15 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opOperandNames[i], true); - op_getters += llvm::formatv( - "::mlir::Value get{0}() { return getODSOperands({1}).front(); }\n ", - op, i); + op_getters += llvm::formatv("::mlir::Value get{0}() { return " + "getStructuredOperands({1}).front(); }\n ", + op, i); } for (size_t i = 0; i < opStrings.opResultNames.size(); ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true); res_getters += llvm::formatv( - R"(::mlir::Value get{0}() { return ::llvm::cast<::mlir::Value>(getODSResults({1}).front()); } + R"(::mlir::Value get{0}() { return ::llvm::cast<::mlir::Value>(getStructuredResults({1}).front()); } )", op, i); } @@ -222,7 +221,7 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, ""); stream << llvm::formatv( - R"(static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", + R"(static void build(::mlir::OpBuilder &opBuilder, ::mlir::OperationState &opState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", resultParams, operandParams); dict["OP_BUILD_DECLS"] = buildDecls; @@ -256,7 +255,7 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return failure(); } - llvm::SmallVector opNames; + SmallVector opNames; if (failed(generateOpList(dialect, opNames))) return failure(); @@ -281,6 +280,75 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return success(); } +static std::string generateOpDefinition(irdl::detail::dictionary &dict, + irdl::OperationOp op) { + static const auto perOpDefTemplate = mlir::irdl::detail::Template{ +#include "Templates/PerOperationDef.txt" + }; + + auto opStrings = getStrings(op); + fillDict(dict, opStrings); + + const auto operandCount = opStrings.opOperandNames.size(); + const auto operandNames = + operandCount ? joinNameList(opStrings.opOperandNames) : "{\"\"}"; + + const auto resultNames = joinNameList(opStrings.opResultNames); + + auto resultTypes = llvm::join( + llvm::map_range(opStrings.opResultNames, + [](StringRef attr) -> std::string { + return llvm::formatv("::mlir::Type {0}, ", attr); + }), + ""); + auto operandTypes = llvm::join( + llvm::map_range(opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv("::mlir::Value {0}, ", attr); + }), + ""); + auto operandAdder = + llvm::join(llvm::map_range(opStrings.opOperandNames, + [](StringRef attr) -> std::string { + return llvm::formatv( + " opState.addOperands({0});", attr); + }), + "\n"); + auto resultAdder = llvm::join( + llvm::map_range(opStrings.opResultNames, + [](StringRef attr) -> std::string { + return llvm::formatv(" opState.addTypes({0});", attr); + }), + "\n"); + + const auto buildDefinition = llvm::formatv( + R"( +void {0}::build(::mlir::OpBuilder &opBuilder, ::mlir::OperationState &opState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ +{3} +{4} +} +)", + opStrings.opCppName, std::move(resultTypes), std::move(operandTypes), + std::move(operandAdder), std::move(resultAdder)); + + dict["OP_BUILD_DEFS"] = buildDefinition; + + std::string str; + llvm::raw_string_ostream stream{str}; + perOpDefTemplate.render(stream, dict); + return str; +} + +static std::string +generateTypeVerifierCase(StringRef name, const DialectStrings &dialectStrings) { + return llvm::formatv( + R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { +value = {1}::{0}::get(parser.getContext()); +return ::mlir::success(!!value); +}))", + name, dialectStrings.namespacePath); +} + static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings) { @@ -293,9 +361,6 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, static const auto dialectDefTemplate = mlir::irdl::detail::Template{ #include "Templates/DialectDef.txt" }; - static const auto perOpDefTemplate = mlir::irdl::detail::Template{ -#include "Templates/PerOperationDef.txt" - }; irdl::detail::dictionary dict; fillDict(dict, dialectStrings); @@ -305,8 +370,7 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, typeHeaderDefTemplate.render(output, dict); - // get typedef list - llvm::SmallVector typeNames; + SmallVector typeNames; if (failed(generateTypedefList(dialect, typeNames))) return failure(); @@ -318,18 +382,13 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, }), ",\n"); - auto typeCase = llvm::join( - llvm::map_range( - typeNames, - [&](llvm::StringRef name) -> std::string { - return llvm::formatv( - R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) { - value = {1}::{0}::get(parser.getContext()); - return ::mlir::success(!!value); - }))", - name, dialectStrings.namespacePath); - }), - "\n"); + auto typeVerifierGenerator = + [&dialectStrings](llvm::StringRef name) -> std::string { + return generateTypeVerifierCase(name, dialectStrings); + }; + + auto typeCase = + llvm::join(llvm::map_range(typeNames, typeVerifierGenerator), "\n"); dict["TYPE_PARSER"] = llvm::formatv( R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) { @@ -362,93 +421,34 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, std::move(typePrintCase)); dict["TYPE_DEFINES"] = - llvm::join(llvm::map_range(typeNames, - [&](StringRef name) -> std::string { - return llvm::formatv( - "MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", - name, dialectStrings.namespacePath); - }), - "\n"); + join(map_range(typeNames, + [&](StringRef name) -> std::string { + return formatv("MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})", + name, dialectStrings.namespacePath); + }), + "\n"); typeDefTemplate.render(output, dict); - // get op list auto operations = dialect.getOps(); - llvm::SmallVector opNames; + SmallVector opNames; if (failed(generateOpList(dialect, opNames))) return failure(); const auto commaSeparatedOpList = llvm::join( - llvm::map_range(opNames, - [&dialectStrings](llvm::StringRef name) -> std::string { - return llvm::formatv( - "{0}::{1}", dialectStrings.namespacePath, name); - }), + map_range(opNames, + [&dialectStrings](llvm::StringRef name) -> std::string { + return llvm::formatv("{0}::{1}", dialectStrings.namespacePath, + name); + }), ",\n"); - const auto perOpDefinitions = llvm::join( - llvm::map_range( - operations, - [&dict, &perOpDefTemplate = - perOpDefTemplate](irdl::OperationOp op) -> std::string { - auto opStrings = getStrings(op); - fillDict(dict, opStrings); - - const auto operandCount = opStrings.opOperandNames.size(); - const auto operandNames = - operandCount ? joinNameList(opStrings.opOperandNames) - : "{\"\"}"; - - const auto resultNames = joinNameList(opStrings.opResultNames); - - auto resultTypes = - llvm::join(llvm::map_range(opStrings.opResultNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - "::mlir::Type {0}, ", attr); - }), - ""); - auto operandTypes = - llvm::join(llvm::map_range(opStrings.opOperandNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - "::mlir::Value {0}, ", attr); - }), - ""); - auto odsOperandAdder = llvm::join( - llvm::map_range(opStrings.opOperandNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - " odsState.addOperands({0});", attr); - }), - "\n"); - auto odsResultAdder = llvm::join( - llvm::map_range(opStrings.opResultNames, - [](StringRef attr) -> std::string { - return llvm::formatv( - " odsState.addTypes({0});", attr); - }), - "\n"); - - const auto buildDefinition = llvm::formatv( - R"( -void {0}::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{ -{3} -{4} -} - )", - opStrings.opCppName, std::move(resultTypes), - std::move(operandTypes), std::move(odsOperandAdder), - std::move(odsResultAdder)); - - dict["OP_BUILD_DEFS"] = buildDefinition; - - std::string str; - llvm::raw_string_ostream stream{str}; - perOpDefTemplate.render(stream, dict); - return str; - }), - "\n"); + const auto opDefinitionGenerator = [&dict](irdl::OperationOp op) { + return generateOpDefinition(dict, op); + }; + + const auto perOpDefinitions = + llvm::join(llvm::map_range(operations, opDefinitionGenerator), "\n"); dict["OP_LIST"] = commaSeparatedOpList; dict["OP_CLASSES"] = perOpDefinitions; @@ -468,9 +468,22 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { .Case( ([](irdl::OperationOp) { return success(); })) .Case(([](irdl::TypeOp) { return success(); })) - .Case( - ([](irdl::OperandsOp) { return success(); })) - .Case(([](irdl::ResultsOp) { return success(); })) + .Case(([](irdl::OperandsOp op) { + if (llvm::all_of( + op.getVariadicity(), [](irdl::VariadicityAttr attr) { + return attr.getValue() == irdl::Variadicity::single; + })) + return success(); + return failure(); + })) + .Case(([](irdl::ResultsOp op) { + if (llvm::all_of( + op.getVariadicity(), [](irdl::VariadicityAttr attr) { + return attr.getValue() == irdl::Variadicity::single; + })) + return success(); + return failure(); + })) .Case(([](irdl::AnyOp) { return success(); })) .Default([](mlir::Operation *op) -> LogicalResult { return op->emitError("IRDL C++ translation does not yet support " @@ -503,8 +516,7 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, return failure(); } - llvm::SmallVector> namespaceAbsolutePath{{"mlir"}, - dialectName}; + SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; std::string namespaceOpen; std::string namespaceClose; std::string namespacePath; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 68733ee35ae2c..340d27ce26cc2 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -14,7 +14,7 @@ public: public: __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} - std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize) { + std::pair getStructuredOperandIndexAndLength(unsigned index, unsigned odsOperandsSize) { return {index, __OP_OPERAND_COUNT__}; } @@ -45,12 +45,12 @@ public: template >> __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} - std::pair getODSOperandIndexAndLength(unsigned index) { - return Base::getODSOperandIndexAndLength(index, odsOperands.size()); + std::pair getStructuredOperandIndexAndLength(unsigned index) { + return Base::getStructuredOperandIndexAndLength(index, odsOperands.size()); } - RangeT getODSOperands(unsigned index) { - auto valueRange = getODSOperandIndexAndLength(index); + RangeT getStructuredOperands(unsigned index) { + auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(odsOperands.begin(), valueRange.first), std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } @@ -109,22 +109,22 @@ public: return getResultNames()[index]; } - std::pair getODSOperandIndexAndLength(unsigned index) { + std::pair getStructuredOperandIndexAndLength(unsigned index) { return {index, __OP_OPERAND_COUNT__}; } - ::mlir::Operation::operand_range getODSOperands(unsigned index) { - auto valueRange = getODSOperandIndexAndLength(index); + ::mlir::Operation::operand_range getStructuredOperands(unsigned index) { + auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } - std::pair getODSResultIndexAndLength(unsigned index) { + std::pair getStructuredResultIndexAndLength(unsigned index) { return {index, __OP_RESULT_COUNT__}; } - ::mlir::Operation::result_range getODSResults(unsigned index) { - auto valueRange = getODSResultIndexAndLength(index); + ::mlir::Operation::result_range getStructuredResults(unsigned index) { + auto valueRange = getStructuredResultIndexAndLength(index); return {std::next(getOperation()->result_begin(), valueRange.first), std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir index 7d7bae72059f5..30f27934857a5 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test.testd.mlir @@ -1,6 +1,6 @@ // RUN: mlir-opt %s | FileCheck %s // CHECK: module { -// CHECK-LABEL: [[v1: *]] = "test_irdl_to_cpp.bar" +// CHECK-NEXT: [[v1:[^ ]+]] = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo module { %0 = "test_irdl_to_cpp.bar"() : () -> !test_irdl_to_cpp.foo } From cf508a9df19eae2eb01a6dd812ec452617676aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Tue, 1 Apr 2025 22:20:31 +0200 Subject: [PATCH 70/94] fix templates --- .../IRDLToCpp/Templates/PerOperationDecl.txt | 15 ++++++++++++--- .../IRDLToCpp/Templates/PerOperationDef.txt | 2 +- mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt | 4 ++++ mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt | 3 ++- .../Target/IRDLToCpp/Templates/TypeHeaderDecl.txt | 2 +- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 3 +++ .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 1 + 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 340d27ce26cc2..f5ea8665a170a 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -14,13 +14,15 @@ public: public: __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} + /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. std::pair getStructuredOperandIndexAndLength(unsigned index, unsigned odsOperandsSize) { - return {index, __OP_OPERAND_COUNT__}; + return {index, 1}; } const Properties &getProperties() { return properties; } + ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } @@ -42,13 +44,16 @@ public: __OP_CPP_NAME__GenericAdaptor(RangeT values, const __OP_CPP_NAME__GenericAdaptorBase &base) : Base(base), odsOperands(values) {} + // HACK ALERT: This template parameter allows using __OP_CPP_NAME__ which is declared later. template >> __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} + /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. std::pair getStructuredOperandIndexAndLength(unsigned index) { return Base::getStructuredOperandIndexAndLength(index, odsOperands.size()); } + /// Get the n-th structured operand (single value, variadic or optional). RangeT getStructuredOperands(unsigned index) { auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(odsOperands.begin(), valueRange.first), @@ -109,20 +114,24 @@ public: return getResultNames()[index]; } + /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. std::pair getStructuredOperandIndexAndLength(unsigned index) { - return {index, __OP_OPERAND_COUNT__}; + return {index, 1}; } + /// Get the n-th structured operand (single value, variadic or optional). ::mlir::Operation::operand_range getStructuredOperands(unsigned index) { auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } + /// Return the unstructured result index of a structured result along with the amount of unstructured results it contains. std::pair getStructuredResultIndexAndLength(unsigned index) { - return {index, __OP_RESULT_COUNT__}; + return {index, 1}; } + /// Get the n-th structured result (single value, variadic or optional). ::mlir::Operation::result_range getStructuredResults(unsigned index) { auto valueRange = getStructuredResultIndexAndLength(index); return {std::next(getOperation()->result_begin(), valueRange.first), diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index ac80d382d4ceb..02f903055ccc6 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -20,4 +20,4 @@ void __OP_CPP_NAME__::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationStat __NAMESPACE_CLOSE__ MLIR_DEFINE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__OP_CPP_NAME__) -)" \ No newline at end of file +)" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index a34259f904d03..f58f48d978cca 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -1,5 +1,9 @@ R"( +//===----------------------------------------------------------------------===// +// __NAMESPACE_PATH__::__TYPE_CPP_NAME__ declarations +//===----------------------------------------------------------------------===// + __NAMESPACE_OPEN__ class __TYPE_CPP_NAME__ : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, __DIALECT_BASE_TYPE_NAME__, ::mlir::TypeStorage> { diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index e78182c63995d..ade493e6252b0 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -21,6 +21,7 @@ __TYPE_PRINTER__ << mnemonic << "` in dialect `" << getNamespace() << "`"; return {}; } + /// Print a type registered to this dialect. void __DIALECT_CPP_NAME__::printType(::mlir::Type type, ::mlir::DialectAsmPrinter &printer) const { @@ -29,4 +30,4 @@ void __DIALECT_CPP_NAME__::printType(::mlir::Type type, } __NAMESPACE_CLOSE__ -)" \ No newline at end of file +)" diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt index ec54be7352715..878bbdb7d3bd2 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeHeaderDecl.txt @@ -11,4 +11,4 @@ public: __NAMESPACE_CLOSE__ MLIR_DECLARE_EXPLICIT_TYPE_ID(__NAMESPACE_PATH__::__DIALECT_BASE_TYPE_NAME__) -)" \ No newline at end of file +)" diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index cc10506d7b804..9ba0f5979cea4 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -41,6 +41,9 @@ struct TestOpConversion : public OpConversionPattern { LogicalResult matchAndRewrite(mlir::test_irdl_to_cpp::BeefOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + assert(adaptor.getODSOperands(0).size() == 1); + assert(adaptor.getODSOperands(1).size() == 1); + auto bar = rewriter.replaceOpWithNewOp( op, op->getResultTypes().front()); rewriter.setInsertionPointAfter(bar); diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index ee80c8929754d..45ba29d7c9ec5 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -1,4 +1,5 @@ // RUN: mlir-irdl-to-cpp %s + irdl.dialect @test_irdl_to_cpp { irdl.type @foo From da169512ff0d87fd320ea4f3a78adf7e1ad657f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Tue, 1 Apr 2025 22:25:31 +0200 Subject: [PATCH 71/94] add comments and fix bug --- mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index 9ba0f5979cea4..d7fa8369019ae 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -41,8 +41,8 @@ struct TestOpConversion : public OpConversionPattern { LogicalResult matchAndRewrite(mlir::test_irdl_to_cpp::BeefOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - assert(adaptor.getODSOperands(0).size() == 1); - assert(adaptor.getODSOperands(1).size() == 1); + assert(adaptor.getStructuredOperands(0).size() == 1); + assert(adaptor.getStructuredOperands(1).size() == 1); auto bar = rewriter.replaceOpWithNewOp( op, op->getResultTypes().front()); From 784b04d8be35caa7c133318e162888c4084d9e9d Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 1 Apr 2025 20:31:59 +0000 Subject: [PATCH 72/94] extracted getters and builders --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 44 +++++++++++++++---------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index d7b69e060023f..837d337a05f2f 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -169,36 +169,33 @@ static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, return success(); } -static LogicalResult generateOperationInclude(irdl::OperationOp op, - raw_ostream &output, - irdl::detail::dictionary &dict) { - static const auto perOpDeclTemplate = irdl::detail::Template( -#include "Templates/PerOperationDecl.txt" - ); - const auto opStrings = getStrings(op); - fillDict(dict, opStrings); - - auto op_getters = std::string{}; - auto res_getters = std::string{}; +static void generateOpGetterDeclarations(irdl::detail::dictionary &dict, + const OpStrings &opStrings) { + auto opGetters = std::string{}; + auto resGetters = std::string{}; for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opOperandNames[i], true); - op_getters += llvm::formatv("::mlir::Value get{0}() { return " - "getStructuredOperands({1}).front(); }\n ", - op, i); + opGetters += llvm::formatv("::mlir::Value get{0}() { return " + "getStructuredOperands({1}).front(); }\n ", + op, i); } for (size_t i = 0; i < opStrings.opResultNames.size(); ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true); - res_getters += llvm::formatv( + resGetters += llvm::formatv( R"(::mlir::Value get{0}() { return ::llvm::cast<::mlir::Value>(getStructuredResults({1}).front()); } )", op, i); } - dict["OP_OPERAND_GETTER_DECLS"] = op_getters; - dict["OP_RESULT_GETTER_DECLS"] = res_getters; + dict["OP_OPERAND_GETTER_DECLS"] = opGetters; + dict["OP_RESULT_GETTER_DECLS"] = resGetters; +} + +static void generateOpBuilderDeclarations(irdl::detail::dictionary &dict, + const OpStrings &opStrings) { std::string buildDecls; llvm::raw_string_ostream stream{buildDecls}; @@ -224,6 +221,19 @@ static LogicalResult generateOperationInclude(irdl::OperationOp op, R"(static void build(::mlir::OpBuilder &opBuilder, ::mlir::OperationState &opState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)", resultParams, operandParams); dict["OP_BUILD_DECLS"] = buildDecls; +} + +static LogicalResult generateOperationInclude(irdl::OperationOp op, + raw_ostream &output, + irdl::detail::dictionary &dict) { + static const auto perOpDeclTemplate = irdl::detail::Template( +#include "Templates/PerOperationDecl.txt" + ); + const auto opStrings = getStrings(op); + fillDict(dict, opStrings); + + generateOpGetterDeclarations(dict, opStrings); + generateOpBuilderDeclarations(dict, opStrings); perOpDeclTemplate.render(output, dict); return success(); From e980d88bbee21ad5b14c7c97008e7432eaabafc9 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Wed, 2 Apr 2025 14:20:50 +0000 Subject: [PATCH 73/94] fixed comments --- mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h index 2587cb4b65638..940ce5632cb41 100644 --- a/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h +++ b/mlir/include/mlir/Target/IRDLToCpp/IRDLToCpp.h @@ -1,4 +1,4 @@ -//===- TranslationRegistration.h - Register translation ---------*- C++ -*-===// +//===- IRDLToCpp.h - Register translation -----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,8 +21,7 @@ namespace irdl { /// Translates an IRDL dialect definition to a C++ definition that can be used /// with MLIR. /// -/// As with TableGen declarations, the following preprocessor macros will -/// generate the corresponding code: +/// The following preprocessor macros will generate the following code: /// /// // This define generates code for the dialect's class declarations /// #define GEN_DIALECT_DECL_HEADER From c26e36d516fb8dba47f62c93f90b2746dc7769a1 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 4 Apr 2025 09:42:40 +0000 Subject: [PATCH 74/94] fixed multidialect bug --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 63 ++++++++++++++----------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 837d337a05f2f..3c300ff3f9b96 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -1,6 +1,6 @@ //===- IRDLToCpp.cpp - Converts IRDL definitions to C++ -------------------===// // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// Part of the LLVM Project, under the A0ache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // @@ -31,14 +31,14 @@ constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; namespace { struct DialectStrings { - StringRef dialectName; - StringRef dialectCppName; - StringRef dialectCppShortName; - StringRef dialectBaseTypeName; - - StringRef namespaceOpen; - StringRef namespaceClose; - StringRef namespacePath; + std::string dialectName; + std::string dialectCppName; + std::string dialectCppShortName; + std::string dialectBaseTypeName; + + std::string namespaceOpen; + std::string namespaceClose; + std::string namespacePath; }; struct TypeStrings { @@ -248,8 +248,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, static const auto typeHeaderDeclTemplate = irdl::detail::Template( #include "Templates/TypeHeaderDecl.txt" ); - output << "#ifdef " << declarationMacroFlag << "\n#undef " - << declarationMacroFlag << "\n"; irdl::detail::dictionary dict; fillDict(dict, dialectStrings); @@ -285,8 +283,6 @@ static LogicalResult generateInclude(irdl::DialectOp dialect, return failure(); } - output << "#endif // " << declarationMacroFlag << "\n"; - return success(); } @@ -375,9 +371,6 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, irdl::detail::dictionary dict; fillDict(dict, dialectStrings); - output << "#ifdef " << definitionMacroFlag << "\n#undef " - << definitionMacroFlag << "\n"; - typeHeaderDefTemplate.render(output, dict); SmallVector typeNames; @@ -465,7 +458,6 @@ static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, output << perOpDefinitions; dialectDefTemplate.render(output, dict); - output << "#endif // " << definitionMacroFlag << "\n"; return success(); } @@ -517,14 +509,13 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, #include "Templates/TypeDef.txt" ); - llvm::LogicalResult result = success(); + llvm::SmallMapVector dialectStringTable; for (auto dialect : dialects) { - StringRef dialectName = dialect.getSymName(); - - if (failed(verifySupported(dialect))) { + if (failed(verifySupported(dialect))) return failure(); - } + + StringRef dialectName = dialect.getSymName(); SmallVector> namespaceAbsolutePath{{"mlir"}, dialectName}; std::string namespaceOpen; @@ -553,18 +544,34 @@ irdl::translateIRDLDialectToCpp(llvm::ArrayRef dialects, dialectStrings.namespaceClose = namespaceClose; dialectStrings.namespacePath = namespacePath; - output << headerTemplateText; + dialectStringTable[dialect] = std::move(dialectStrings); + } + + // generate the actual header + output << headerTemplateText; - if (failed(generateInclude(dialect, output, dialectStrings))) { + output << llvm::formatv("#ifdef {0}\n#undef {0}\n", declarationMacroFlag); + for (auto dialect : dialects) { + + auto &dialectStrings = dialectStringTable[dialect]; + auto &dialectName = dialectStrings.dialectName; + + if (failed(generateInclude(dialect, output, dialectStrings))) return dialect->emitError("Error in Dialect " + dialectName + " while generating headers"); - } + } + output << llvm::formatv("#endif // #ifdef {}\n", declarationMacroFlag); + + output << llvm::formatv("#ifdef {0}\n#undef {0}\n ", definitionMacroFlag); + for (auto &dialect : dialects) { + auto &dialectStrings = dialectStringTable[dialect]; + auto &dialectName = dialectStrings.dialectName; - if (failed(generateLib(dialect, output, dialectStrings))) { + if (failed(generateLib(dialect, output, dialectStrings))) return dialect->emitError("Error in Dialect " + dialectName + " while generating library"); - } } + output << llvm::formatv("#endif // #ifdef {}\n", definitionMacroFlag); - return result; + return success(); } From bc37a24cdbd08f856ca23b4f60593350df63d685 Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:45:01 +0100 Subject: [PATCH 75/94] Update mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp Co-authored-by: Fehr Mathieu --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 3c300ff3f9b96..2df44c63e6d3b 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -83,9 +83,7 @@ static OpStrings getStrings(irdl::OperationOp op) { auto operandOp = operands.empty() ? std::optional{} : *operands.begin(); - auto results = op.getOps(); - auto resultOp = - results.empty() ? std::optional{} : *results.begin(); + auto resultOp = op.getOp(); OpStrings strings; strings.opName = op.getSymName(); From e51ae35a324ef041435053e7dcd2425e19d1a6e4 Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:45:12 +0100 Subject: [PATCH 76/94] Update mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp Co-authored-by: Fehr Mathieu --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 2df44c63e6d3b..dabf836f8e332 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -79,9 +79,7 @@ static TypeStrings getStrings(irdl::TypeOp type) { } static OpStrings getStrings(irdl::OperationOp op) { - auto operands = op.getOps(); - auto operandOp = - operands.empty() ? std::optional{} : *operands.begin(); + auto operandOp = op.getOp(); auto resultOp = op.getOp(); From ef16ac506e3f2ced767681a66c9019dee12200e2 Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:45:33 +0100 Subject: [PATCH 77/94] Update mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp Co-authored-by: Fehr Mathieu --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index dabf836f8e332..2bb733c5a4cf4 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -170,7 +170,7 @@ static void generateOpGetterDeclarations(irdl::detail::dictionary &dict, auto opGetters = std::string{}; auto resGetters = std::string{}; - for (size_t i = 0; i < opStrings.opOperandNames.size(); ++i) { + for (size_t i = 0, end = opStrings.opOperandNames.size(); i < end; ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opOperandNames[i], true); opGetters += llvm::formatv("::mlir::Value get{0}() { return " From e21a21f0e9b6413479c1ebafb8ae225c847e99b5 Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:46:14 +0100 Subject: [PATCH 78/94] Update mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp Co-authored-by: Fehr Mathieu --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 2bb733c5a4cf4..47cd42c63f57a 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -177,7 +177,7 @@ static void generateOpGetterDeclarations(irdl::detail::dictionary &dict, "getStructuredOperands({1}).front(); }\n ", op, i); } - for (size_t i = 0; i < opStrings.opResultNames.size(); ++i) { + for (size_t i = 0, end = opStrings.opResultNames.size(); i < end; ++i) { const auto op = llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true); resGetters += llvm::formatv( From c79ddcd04972fcd52ee9f909cccc9478ca2eed1b Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 4 Apr 2025 09:49:47 +0000 Subject: [PATCH 79/94] PR suggestions --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 47cd42c63f57a..16e12c02158e6 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -466,27 +466,29 @@ static LogicalResult verifySupported(irdl::DialectOp dialect) { .Case( ([](irdl::OperationOp) { return success(); })) .Case(([](irdl::TypeOp) { return success(); })) - .Case(([](irdl::OperandsOp op) { + .Case(([](irdl::OperandsOp op) -> LogicalResult { if (llvm::all_of( op.getVariadicity(), [](irdl::VariadicityAttr attr) { return attr.getValue() == irdl::Variadicity::single; })) return success(); - return failure(); + return op.emitError("IRDL C++ translation does not yet support " + "variadic operations"); })) - .Case(([](irdl::ResultsOp op) { + .Case(([](irdl::ResultsOp op) -> LogicalResult { if (llvm::all_of( op.getVariadicity(), [](irdl::VariadicityAttr attr) { return attr.getValue() == irdl::Variadicity::single; })) return success(); - return failure(); + return op.emitError( + "IRDL C++ translation does not yet support variadic results"); })) .Case(([](irdl::AnyOp) { return success(); })) .Default([](mlir::Operation *op) -> LogicalResult { return op->emitError("IRDL C++ translation does not yet support " "translation of ") - << op->getName() << "operation"; + << op->getName() << " operation"; }); if (failed(res)) From 5ef348a83e02c0b3d3bae031217e79243a24c51a Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 4 Apr 2025 10:10:11 +0000 Subject: [PATCH 80/94] more PR fixes --- .../TestIRDLToCpp/TestIRDLToCppDialect.cpp | 3 +-- .../Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h | 3 +-- ...dl_to_cpp_invalid_unsupported_types.irdl.mlir | 16 ++++++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp index d7fa8369019ae..bda614a97ab42 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.cpp @@ -1,5 +1,4 @@ -//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -//-*-===// +//===- TestIRDLToCppDialect.cpp - MLIR Test Dialect Types ---------------*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h index 03aa528a42ecd..5d2e3d7b4cd48 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/TestIRDLToCppDialect.h @@ -1,5 +1,4 @@ -//===- TestDialect.cpp - MLIR Test Dialect Types ------------------*- C++ -//-*-===// +//===- TestIRDLToCppDialect.h - MLIR Test Dialect Types -----------------*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir index 3e42a09537871..403b49235467c 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_unsupported_types.irdl.mlir @@ -2,7 +2,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.operation @results_no_any_of { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.any_ofoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.any_of operation}} %1 = irdl.any_of(%0, %0) irdl.results(res: %1) } @@ -12,7 +12,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @operands_no_any_of { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.all_ofoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.all_of operation}} %1 = irdl.all_of(%0, %0) irdl.operands(test: %1) irdl.results(res: %0) @@ -22,7 +22,7 @@ irdl.dialect @test_irdl_to_cpp { // ----- irdl.dialect @test_irdl_to_cpp { - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attributeoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attribute operation}} irdl.attribute @no_attrs } @@ -31,7 +31,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attributesoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.attributes operation}} irdl.attributes { "attr" = %0 } @@ -43,7 +43,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.type @ty { %0 = irdl.any - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.parametersoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.parameters operation}} irdl.parameters(ty: %0) } } @@ -52,7 +52,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.regionoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.region operation}} %0 = irdl.region() irdl.regions(reg: %0) } @@ -63,7 +63,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.operation @test_op { - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.regionsoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.regions operation}} irdl.regions() } @@ -73,7 +73,7 @@ irdl.dialect @test_irdl_to_cpp { irdl.dialect @test_irdl_to_cpp { irdl.type @test_derived { - // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.baseoperation}} + // expected-error@+1 {{IRDL C++ translation does not yet support translation of irdl.base operation}} %0 = irdl.base "!builtin.integer" } } From a30bb8dae65d579a6232ee8f80cf3a8471beb326 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 4 Apr 2025 10:14:46 +0000 Subject: [PATCH 81/94] moved invalid name test --- .../IRDL/invalid_names.irdl.mlir} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mlir/test/{lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir => Dialect/IRDL/invalid_names.irdl.mlir} (100%) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir b/mlir/test/Dialect/IRDL/invalid_names.irdl.mlir similarity index 100% rename from mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp_invalid_names.irdl.mlir rename to mlir/test/Dialect/IRDL/invalid_names.irdl.mlir From b1ccf666d994a6ccbf4880a3f0503cb50595ce2b Mon Sep 17 00:00:00 2001 From: Ivan Ho <38537881+hhkit@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:22:40 +0100 Subject: [PATCH 82/94] Update mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt Co-authored-by: Fehr Mathieu --- mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index f5ea8665a170a..804d5bfad579c 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -44,7 +44,7 @@ public: __OP_CPP_NAME__GenericAdaptor(RangeT values, const __OP_CPP_NAME__GenericAdaptorBase &base) : Base(base), odsOperands(values) {} - // HACK ALERT: This template parameter allows using __OP_CPP_NAME__ which is declared later. + // This template parameter allows using __OP_CPP_NAME__ which is declared later. template >> __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} From aae9e197009fc8bc1d81113310443fc134263f44 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 4 Apr 2025 10:44:47 +0000 Subject: [PATCH 83/94] added basic filecheck for irdl translation --- .../TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir index 45ba29d7c9ec5..42e713e0adecd 100644 --- a/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir +++ b/mlir/test/lib/Dialect/TestIRDLToCpp/test_irdl_to_cpp.irdl.mlir @@ -1,19 +1,32 @@ -// RUN: mlir-irdl-to-cpp %s +// RUN: mlir-irdl-to-cpp %s | FileCheck %s +// CHECK: class TestIrdlToCpp irdl.dialect @test_irdl_to_cpp { + + // CHECK: class FooType irdl.type @foo + // CHECK: class BarOp + // CHECK: ::mlir::Value getRes() irdl.operation @bar { %0 = irdl.any irdl.results(res: %0) } + // CHECK: class BeefOp + // CHECK: ::mlir::Value getLhs() + // CHECK: ::mlir::Value getRhs() + // CHECK: ::mlir::Value getRes() irdl.operation @beef { %0 = irdl.any irdl.operands(lhs: %0, rhs: %0) irdl.results(res: %0) } + // CHECK: class HashOp + // CHECK: ::mlir::Value getLhs() + // CHECK: ::mlir::Value getRhs() + // CHECK: ::mlir::Value getRes() irdl.operation @hash { %0 = irdl.any irdl.operands(lhs: %0, rhs: %0) From 29581b7811e9d822fe7b887375bb18b56a69ba67 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Tue, 8 Apr 2025 15:03:25 +0000 Subject: [PATCH 84/94] comments, as requested by PR --- mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp | 10 ++++++++++ mlir/lib/Target/IRDLToCpp/TemplatingUtils.h | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp index 16e12c02158e6..538ea4f450b29 100644 --- a/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp +++ b/mlir/lib/Target/IRDLToCpp/IRDLToCpp.cpp @@ -30,6 +30,7 @@ constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF"; namespace { +/// The set of strings that can be generated from a Dialect declaraiton struct DialectStrings { std::string dialectName; std::string dialectCppName; @@ -41,11 +42,13 @@ struct DialectStrings { std::string namespacePath; }; +/// The set of strings that can be generated from a Type declaraiton struct TypeStrings { StringRef typeName; std::string typeCppName; }; +/// The set of strings that can be generated from an Operation declaraiton struct OpStrings { StringRef opName; std::string opCppName; @@ -61,16 +64,19 @@ static std::string joinNameList(llvm::ArrayRef names) { return nameArray; } +/// Generates the C++ type name for a TypeOp static std::string typeToCppName(irdl::TypeOp type) { return llvm::formatv("{0}Type", convertToCamelFromSnakeCase(type.getSymName(), true)); } +/// Generates the C++ class name for an OperationOp static std::string opToCppName(irdl::OperationOp op) { return llvm::formatv("{0}Op", convertToCamelFromSnakeCase(op.getSymName(), true)); } +/// Generates TypeStrings from a TypeOp static TypeStrings getStrings(irdl::TypeOp type) { TypeStrings strings; strings.typeName = type.getSymName(); @@ -78,6 +84,7 @@ static TypeStrings getStrings(irdl::TypeOp type) { return strings; } +/// Generates OpStrings from an OperatioOp static OpStrings getStrings(irdl::OperationOp op) { auto operandOp = op.getOp(); @@ -104,12 +111,14 @@ static OpStrings getStrings(irdl::OperationOp op) { return strings; } +/// Fills a dictionary with values from TypeStrings static void fillDict(irdl::detail::dictionary &dict, const TypeStrings &strings) { dict["TYPE_NAME"] = strings.typeName; dict["TYPE_CPP_NAME"] = strings.typeCppName; } +/// Fills a dictionary with values from OpStrings static void fillDict(irdl::detail::dictionary &dict, const OpStrings &strings) { const auto operandCount = strings.opOperandNames.size(); const auto resultCount = strings.opResultNames.size(); @@ -124,6 +133,7 @@ static void fillDict(irdl::detail::dictionary &dict, const OpStrings &strings) { resultCount ? joinNameList(strings.opResultNames) : "{\"\"}"; } +/// Fills a dictionary with values from DialectStrings static void fillDict(irdl::detail::dictionary &dict, const DialectStrings &strings) { dict["DIALECT_NAME"] = strings.dialectName; diff --git a/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h index 1c46a5550f7c4..142821b5434c1 100644 --- a/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h +++ b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h @@ -18,8 +18,15 @@ namespace mlir::irdl::detail { +/// A dictionary stores a mapping of template variables to their assigned +/// variables using dictionary = llvm::StringMap>; +/// Template Code as used by IRDL-to-Cpp. +/// +/// For efficiency, produces a bytecode representation of an input string +/// - LiteralToken: A contiguous stream of characters to be printed +/// - ReplacementToken: A template variable that will be replaced class Template { public: Template(llvm::StringRef str) { @@ -40,6 +47,8 @@ class Template { } } + // Render will apply a dictionary to the Template + // and send it to the specified output stream void render(llvm::raw_ostream &out, const dictionary &replacements) const { for (auto instruction : bytecode) { std::visit( From 180f3a5fb8f4d31ee5c8bb35917ea79cd4baf70f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Fri, 25 Apr 2025 20:03:29 +0200 Subject: [PATCH 85/94] hopefully fix CMake problems --- mlir/cmake/modules/IRDLToCpp.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mlir/cmake/modules/IRDLToCpp.cmake b/mlir/cmake/modules/IRDLToCpp.cmake index 8365f5fd8bfe0..8470ccdf55166 100644 --- a/mlir/cmake/modules/IRDLToCpp.cmake +++ b/mlir/cmake/modules/IRDLToCpp.cmake @@ -2,8 +2,11 @@ function(add_irdl_to_cpp_target target irdl_file) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc COMMAND ${MLIR_IRDL_TO_CPP_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/${irdl_file} -o ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc - DEPENDS ${MLIR_IRDL_TO_CPP_TARGET} ${irdl_file} + + # The command output depends on the executable to ensure IRDL sources are properly rebuilt + # if the tool changes. + DEPENDS ${MLIR_IRDL_TO_CPP_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/${irdl_file} COMMENT "Building ${irdl_file}..." ) - add_custom_target(${target} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc) + add_custom_target(${target} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${irdl_file}.cpp.inc) endfunction() From c6b1fcd0521efbab86b718a1da974a98654aa9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Sat, 26 Apr 2025 16:03:38 +0200 Subject: [PATCH 86/94] hopefully make CI happy about templates --- mlir/lib/Target/IRDLToCpp/TemplatingUtils.h | 50 ++++++++++----------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h index 142821b5434c1..aeb3c09543213 100644 --- a/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h +++ b/mlir/lib/Target/IRDLToCpp/TemplatingUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef IRDLTOCPP_TEMPLATE_UTILS_H -#define IRDLTOCPP_TEMPLATE_UTILS_H +#ifndef MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H +#define MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" @@ -18,13 +18,13 @@ namespace mlir::irdl::detail { -/// A dictionary stores a mapping of template variables to their assigned -/// variables +/// A dictionary stores a mapping of template variable names to their assigned +/// string values. using dictionary = llvm::StringMap>; /// Template Code as used by IRDL-to-Cpp. /// -/// For efficiency, produces a bytecode representation of an input string +/// For efficiency, produces a bytecode representation of an input template. /// - LiteralToken: A contiguous stream of characters to be printed /// - ReplacementToken: A template variable that will be replaced class Template { @@ -47,30 +47,28 @@ class Template { } } - // Render will apply a dictionary to the Template - // and send it to the specified output stream + /// Render will apply a dictionary to the Template and send the rendered + /// result to the specified output stream. void render(llvm::raw_ostream &out, const dictionary &replacements) const { for (auto instruction : bytecode) { - std::visit( - [&](auto &&inst) { - using T = std::decay_t; - if constexpr (std::is_same_v) { - out << inst.text; - } else if constexpr (std::is_same_v) { - auto replacement = replacements.find(inst.keyName); + if (auto *inst = std::get_if(&instruction)) { + out << inst->text; + continue; + } + + if (auto *inst = std::get_if(&instruction)) { + auto replacement = replacements.find(inst->keyName); #ifndef NDEBUG - if (replacement == replacements.end()) { - llvm::errs() - << "Missing template key: " << inst.keyName << "\n"; - llvm_unreachable("Missing template key"); - } + if (replacement == replacements.end()) { + llvm::errs() << "Missing template key: " << inst->keyName << "\n"; + llvm_unreachable("Missing template key"); + } #endif - out << replacement->second; - } else { - static_assert(false, "non-exhaustive visitor!"); - } - }, - instruction); + out << replacement->second; + continue; + } + + llvm_unreachable("non-exhaustive bytecode visit"); } } @@ -88,4 +86,4 @@ class Template { } // namespace mlir::irdl::detail -#endif // #ifndef IRDLTOCPP_TEMPLATE_UTILS_H +#endif // MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H From fafc0ee99bc424d84ceb8550f8835ea3e829e0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Sat, 26 Apr 2025 19:11:49 +0200 Subject: [PATCH 87/94] simplify processBuffer code to please MSVC --- .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 01721b86a55b3..38932fa88d575 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -27,8 +27,7 @@ #include "llvm/Support/ToolOutputFile.h" using namespace mlir; -/// Parses the memory buffer. If successfully, run a series of passes against -/// it and print the result. + static LogicalResult processBuffer(llvm::raw_ostream &os, std::unique_ptr ownedBuffer, @@ -43,40 +42,32 @@ processBuffer(llvm::raw_ostream &os, ctx.printOpOnDiagnostic(!verifyDiagnostics); - using SourceDiagnosticHandlerVariant = - std::variant; - - auto sourceMgrHandler = - verifyDiagnostics - ? SourceDiagnosticHandlerVariant( - std::in_place_type_t{}, - *sourceMgr, &ctx) - : SourceDiagnosticHandlerVariant( - std::in_place_type_t{}, *sourceMgr, - &ctx); - - const auto verifyOr = - [verifier = std::get_if( - &sourceMgrHandler)](LogicalResult res) -> LogicalResult { - return verifier ? verifier->verify() : res; - }; + auto runTranslation = [&]() { + ParserConfig parseConfig(&ctx); + OwningOpRef op = + parseSourceFileForTool(sourceMgr, parseConfig, true); + if (!op) + return failure(); - ParserConfig parseConfig(&ctx); - OwningOpRef op = - parseSourceFileForTool(sourceMgr, parseConfig, true); - if (!op) - return verifyOr(failure()); + auto moduleOp = llvm::cast(*op); + llvm::SmallVector dialects{ + moduleOp.getOps(), + }; - auto moduleOp = llvm::cast(*op); - llvm::SmallVector dialects{ - moduleOp.getOps(), + return irdl::translateIRDLDialectToCpp(dialects, os); }; - if (failed(irdl::translateIRDLDialectToCpp(dialects, os))) - return verifyOr(failure()); + if (!verifyDiagnostics) { + // If no errors are expected, return translation result. + SourceMgrDiagnosticHandler srcManagerHandler(*sourceMgr, &ctx); + return runTranslation(); + } - return verifyOr(success()); + // If errors are expected, ignore translation result and check for + // diagnostics. + SourceMgrDiagnosticVerifierHandler srcManagerHandler(*sourceMgr, &ctx); + (void)runTranslation(); + return srcManagerHandler.verify(); } static LogicalResult translateIRDLToCpp(int argc, char **argv) { From 2abd9dcbbb9bb8bed873ba9e2166df80e4ff1775 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Mon, 28 Apr 2025 13:03:44 +0000 Subject: [PATCH 88/94] wrap at 80 cols --- .../Target/IRDLToCpp/Templates/DialectDef.txt | 3 +- .../IRDLToCpp/Templates/PerOperationDecl.txt | 80 +++++++++++++------ .../IRDLToCpp/Templates/PerOperationDef.txt | 7 +- .../Target/IRDLToCpp/Templates/TypeDecl.txt | 8 +- .../Target/IRDLToCpp/Templates/TypeDef.txt | 4 +- 5 files changed, 73 insertions(+), 29 deletions(-) diff --git a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt index ec55c644116f6..cd52de11dd6b0 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/DialectDef.txt @@ -3,7 +3,8 @@ R"( __NAMESPACE_OPEN__ __DIALECT_CPP_NAME__::__DIALECT_CPP_NAME__(::mlir::MLIRContext *context) - : ::mlir::Dialect(getDialectNamespace(), context, ::mlir::TypeID::get<__DIALECT_CPP_NAME__>()) + : ::mlir::Dialect(getDialectNamespace(), context, + ::mlir::TypeID::get<__DIALECT_CPP_NAME__>()) { initialize(); } diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt index 804d5bfad579c..9e787b8056a89 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDecl.txt @@ -12,10 +12,16 @@ public: struct Properties { }; public: - __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), odsRegions(op->getRegions()) {} - - /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. - std::pair getStructuredOperandIndexAndLength(unsigned index, unsigned odsOperandsSize) { + __OP_CPP_NAME__GenericAdaptorBase(::mlir::Operation *op) + : odsAttrs(op->getRawDictionaryAttrs()), odsOpName(op->getName()), + odsRegions(op->getRegions()) + {} + + /// Return the unstructured operand index of a structured operand along with + // the amount of unstructured operands it contains. + std::pair + getStructuredOperandIndexAndLength (unsigned index, + unsigned odsOperandsSize) { return {index, 1}; } @@ -36,20 +42,34 @@ protected: } // namespace detail template -class __OP_CPP_NAME__GenericAdaptor : public detail::__OP_CPP_NAME__GenericAdaptorBase { +class __OP_CPP_NAME__GenericAdaptor + : public detail::__OP_CPP_NAME__GenericAdaptorBase { using ValueT = ::llvm::detail::ValueOfRange; using Base = detail::__OP_CPP_NAME__GenericAdaptorBase; public: - __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions = {}) : __OP_CPP_NAME__GenericAdaptor(values, attrs, (properties ? *properties.as<::mlir::EmptyProperties *>() : ::mlir::EmptyProperties{}), regions) {} - - __OP_CPP_NAME__GenericAdaptor(RangeT values, const __OP_CPP_NAME__GenericAdaptorBase &base) : Base(base), odsOperands(values) {} - - // This template parameter allows using __OP_CPP_NAME__ which is declared later. - template >> - __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} - - /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. - std::pair getStructuredOperandIndexAndLength(unsigned index) { + __OP_CPP_NAME__GenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, + ::mlir::OpaqueProperties properties, + ::mlir::RegionRange regions = {}) + : __OP_CPP_NAME__GenericAdaptor(values, attrs, + (properties ? *properties.as<::mlir::EmptyProperties *>() + : ::mlir::EmptyProperties{}), regions) {} + + __OP_CPP_NAME__GenericAdaptor(RangeT values, + const __OP_CPP_NAME__GenericAdaptorBase &base) + : Base(base), odsOperands(values) {} + + // This template parameter allows using __OP_CPP_NAME__ which is declared + // later. + template >> + __OP_CPP_NAME__GenericAdaptor(RangeT values, LateInst op) + : Base(op), odsOperands(values) {} + + /// Return the unstructured operand index of a structured operand along with + // the amount of unstructured operands it contains. + std::pair + getStructuredOperandIndexAndLength(unsigned index) { return Base::getStructuredOperandIndexAndLength(index, odsOperands.size()); } @@ -57,7 +77,8 @@ public: RangeT getStructuredOperands(unsigned index) { auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(odsOperands.begin(), valueRange.first), - std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; + std::next(odsOperands.begin(), + valueRange.first + valueRange.second)}; } RangeT getOperands() { @@ -70,7 +91,8 @@ private: RangeT odsOperands; }; -class __OP_CPP_NAME__Adaptor : public __OP_CPP_NAME__GenericAdaptor<::mlir::ValueRange> { +class __OP_CPP_NAME__Adaptor + : public __OP_CPP_NAME__GenericAdaptor<::mlir::ValueRange> { public: using __OP_CPP_NAME__GenericAdaptor::__OP_CPP_NAME__GenericAdaptor; __OP_CPP_NAME__Adaptor(__OP_CPP_NAME__ op); @@ -114,8 +136,10 @@ public: return getResultNames()[index]; } - /// Return the unstructured operand index of a structured operand along with the amount of unstructured operands it contains. - std::pair getStructuredOperandIndexAndLength(unsigned index) { + /// Return the unstructured operand index of a structured operand along with + // the amount of unstructured operands it contains. + std::pair + getStructuredOperandIndexAndLength(unsigned index) { return {index, 1}; } @@ -123,11 +147,14 @@ public: ::mlir::Operation::operand_range getStructuredOperands(unsigned index) { auto valueRange = getStructuredOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), - std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; + std::next(getOperation()->operand_begin(), + valueRange.first + valueRange.second)}; } - /// Return the unstructured result index of a structured result along with the amount of unstructured results it contains. - std::pair getStructuredResultIndexAndLength(unsigned index) { + /// Return the unstructured result index of a structured result along with + // the amount of unstructured results it contains. + std::pair + getStructuredResultIndexAndLength(unsigned index) { return {index, 1}; } @@ -135,14 +162,19 @@ public: ::mlir::Operation::result_range getStructuredResults(unsigned index) { auto valueRange = getStructuredResultIndexAndLength(index); return {std::next(getOperation()->result_begin(), valueRange.first), - std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; + std::next(getOperation()->result_begin(), + valueRange.first + valueRange.second)}; } __OP_OPERAND_GETTER_DECLS__ __OP_RESULT_GETTER_DECLS__ __OP_BUILD_DECLS__ - static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + static void build(::mlir::OpBuilder &odsBuilder, + ::mlir::OperationState &odsState, + ::mlir::TypeRange resultTypes, + ::mlir::ValueRange operands, + ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); }; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt index 02f903055ccc6..88f19d0f22ca4 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/PerOperationDef.txt @@ -8,7 +8,12 @@ __NAMESPACE_OPEN__ __OP_BUILD_DEFS__ -void __OP_CPP_NAME__::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) { +void __OP_CPP_NAME__::build(::mlir::OpBuilder &odsBuilder, + ::mlir::OperationState &odsState, + ::mlir::TypeRange resultTypes, + ::mlir::ValueRange operands, + ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) +{ assert(operands.size() == __OP_OPERAND_COUNT__); assert(resultTypes.size() == __OP_RESULT_COUNT__); odsState.addOperands(operands); diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt index f58f48d978cca..201a550a29ef0 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDecl.txt @@ -6,10 +6,14 @@ R"( __NAMESPACE_OPEN__ -class __TYPE_CPP_NAME__ : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, __DIALECT_BASE_TYPE_NAME__, ::mlir::TypeStorage> { +class __TYPE_CPP_NAME__ + : public ::mlir::Type::TypeBase<__TYPE_CPP_NAME__, + __DIALECT_BASE_TYPE_NAME__, + ::mlir::TypeStorage> { public: using Base::Base; - static constexpr ::llvm::StringLiteral name = "__DIALECT_NAME__.__TYPE_NAME__"; + static constexpr ::llvm::StringLiteral name = + "__DIALECT_NAME__.__TYPE_NAME__"; static constexpr ::llvm::StringLiteral dialectName = "__DIALECT_NAME__"; static constexpr ::llvm::StringLiteral getMnemonic() { return {"__TYPE_NAME__"}; diff --git a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt index ade493e6252b0..aaca4430507fb 100644 --- a/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt +++ b/mlir/lib/Target/IRDLToCpp/Templates/TypeDef.txt @@ -9,7 +9,9 @@ __TYPE_PARSER__ __TYPE_PRINTER__ /// Parse a type registered to this dialect. -::mlir::Type __DIALECT_CPP_NAME__::parseType(::mlir::DialectAsmParser &parser) const { +::mlir::Type __DIALECT_CPP_NAME__::parseType(::mlir::DialectAsmParser &parser) + const +{ ::llvm::SMLoc typeLoc = parser.getCurrentLocation(); ::llvm::StringRef mnemonic; ::mlir::Type genType; From 683dcb8707bb66cc28c082a5ae652c18a5c97c59 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 23 May 2025 13:11:50 +0000 Subject: [PATCH 89/94] initialized variable --- mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 38932fa88d575..9ab238cff1fb4 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -79,7 +79,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), llvm::cl::init("-")); - bool verifyDiagnosticsFlag; + bool verifyDiagnosticsFlag{}; std::string splitInputFileFlag; static llvm::cl::opt verifyDiagnostics( "verify-diagnostics", From 396278e5aee2842149ec2ebc5956f8ea711fa0c3 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 23 May 2025 17:09:51 +0000 Subject: [PATCH 90/94] simplified cl flags --- .../mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 9ab238cff1fb4..a63b289ffaea2 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -79,15 +79,13 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), llvm::cl::init("-")); - bool verifyDiagnosticsFlag{}; - std::string splitInputFileFlag; - static llvm::cl::opt verifyDiagnostics( + static llvm::cl::opt verifyDiagnostics( "verify-diagnostics", llvm::cl::desc("Check that emitted diagnostics match " "expected-* lines on the corresponding line"), - llvm::cl::location(verifyDiagnosticsFlag), llvm::cl::init(false)); + llvm::cl::init(false)); - static llvm::cl::opt splitInputFile( + static llvm::cl::opt splitInputFile( "split-input-file", llvm::cl::ValueOptional, llvm::cl::callback([&](const std::string &str) { // Implicit value: use default marker if flag was used without @@ -97,7 +95,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { }), llvm::cl::desc("Split the input file into chunks using the given or " "default marker and process each chunk independently"), - llvm::cl::location(splitInputFileFlag), llvm::cl::init("")); + llvm::cl::init("")); llvm::InitLLVM y(argc, argv); @@ -125,14 +123,16 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { verifyDiagnostics, nullptr); }; - if (splitInputFileFlag.size()) + auto &splitInputFileDelimiter = splitInputFile.getValue(); + if (splitInputFileDelimiter.size()) return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), - splitInputFileFlag, splitInputFileFlag); + splitInputFileDelimiter, + splitInputFileDelimiter); if (failed(chunkFn(std::move(input), output->os()))) return failure(); - if (!verifyDiagnosticsFlag) + if (!verifyDiagnostics) output->keep(); return success(); From 26c5de52b29431176bb3053d365fc259a374420a Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 23 May 2025 17:59:58 +0000 Subject: [PATCH 91/94] minor change --- mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index a63b289ffaea2..3cfbe0aed9df4 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -123,7 +123,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { verifyDiagnostics, nullptr); }; - auto &splitInputFileDelimiter = splitInputFile.getValue(); + StringRef splitInputFileDelimiter{splitInputFile.getValue()}; if (splitInputFileDelimiter.size()) return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), splitInputFileDelimiter, From 7dc72a0d1729fc9ff561233e67cb560f785424a4 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Fri, 23 May 2025 18:00:14 +0000 Subject: [PATCH 92/94] undo change --- mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp index 3cfbe0aed9df4..a63b289ffaea2 100644 --- a/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp +++ b/mlir/tools/mlir-irdl-to-cpp/mlir-irdl-to-cpp.cpp @@ -123,7 +123,7 @@ static LogicalResult translateIRDLToCpp(int argc, char **argv) { verifyDiagnostics, nullptr); }; - StringRef splitInputFileDelimiter{splitInputFile.getValue()}; + auto &splitInputFileDelimiter = splitInputFile.getValue(); if (splitInputFileDelimiter.size()) return splitAndProcessBuffer(std::move(input), chunkFn, output->os(), splitInputFileDelimiter, From 47914c69ab47545ceb5a7bc517ed18882cfb5497 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Sun, 25 May 2025 14:03:42 +0000 Subject: [PATCH 93/94] arrange alphabetically --- mlir/tools/mlir-opt/mlir-opt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 7419a6a467dde..0060aa58117ee 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -252,6 +252,7 @@ void registerTestPasses() { mlir::test::registerTestIRVisitorsPass(); mlir::test::registerTestGenericIRVisitorsPass(); mlir::test::registerTestInterfaces(); + mlir::test::registerTestIrdlTestDialectConversionPass(); mlir::test::registerTestIRVisitorsPass(); mlir::test::registerTestLastModifiedPass(); mlir::test::registerTestLinalgDecomposeOps(); @@ -304,7 +305,6 @@ void registerTestPasses() { mlir::test::registerTestVectorReductionToSPIRVDotProd(); mlir::test::registerTestVulkanRunnerPipeline(); mlir::test::registerTestWrittenToPass(); - mlir::test::registerTestIrdlTestDialectConversionPass(); mlir::test::registerTestXeGPULowerings(); #if MLIR_ENABLE_PDL_IN_PATTERNMATCH mlir::test::registerTestDialectConversionPasses(); @@ -329,12 +329,12 @@ int main(int argc, char **argv) { registerAllGPUToLLVMIRTranslations(registry); #ifdef MLIR_INCLUDE_TESTS + ::test::registerIrdlTestDialect(registry); ::test::registerTestDialect(registry); ::test::registerTestTransformDialectExtension(registry); ::test::registerTestTransformsTransformDialectExtension(registry); ::test::registerTestTilingInterfaceTransformDialectExtension(registry); ::test::registerTestDynDialect(registry); - ::test::registerIrdlTestDialect(registry); #endif return mlir::asMainReturnCode(mlir::MlirOptMain( argc, argv, "MLIR modular optimizer driver\n", registry)); From 2a4a43ea6dabef2d17897d94d4c3d6e52a08e901 Mon Sep 17 00:00:00 2001 From: Ivan Ho Date: Sun, 25 May 2025 14:05:20 +0000 Subject: [PATCH 94/94] actually arrange alphabetically --- mlir/tools/mlir-opt/mlir-opt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 0060aa58117ee..b51da0e0383d6 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -331,10 +331,10 @@ int main(int argc, char **argv) { #ifdef MLIR_INCLUDE_TESTS ::test::registerIrdlTestDialect(registry); ::test::registerTestDialect(registry); + ::test::registerTestDynDialect(registry); + ::test::registerTestTilingInterfaceTransformDialectExtension(registry); ::test::registerTestTransformDialectExtension(registry); ::test::registerTestTransformsTransformDialectExtension(registry); - ::test::registerTestTilingInterfaceTransformDialectExtension(registry); - ::test::registerTestDynDialect(registry); #endif return mlir::asMainReturnCode(mlir::MlirOptMain( argc, argv, "MLIR modular optimizer driver\n", registry));