diff --git a/mlir/include/mlir/Tools/mlir-tblgen/MlirTblgenMain.h b/mlir/include/mlir/Tools/mlir-tblgen/MlirTblgenMain.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Tools/mlir-tblgen/MlirTblgenMain.h @@ -0,0 +1,26 @@ +//===- MlirTblgenMain.h - MLIR Tablegen Driver main -------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Main entry function for mlir-tblgen for when built as standalone binary. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TOOLS_MLIR_TBLGEN_MLIRTBLGENMAIN_H +#define MLIR_TOOLS_MLIR_TBLGEN_MLIRTBLGENMAIN_H + +namespace mlir { +/// Main Program for tools like 'mlir-tblgen' with custom backends. To add +/// a new backend, simply create a new 'mlir::GenRegistration' global variable. +/// See its documentation for more info. +/// +/// The 'argc' and 'argv' arguments are simply forwarded from a main function. +/// The return value is the exit code from llvm::TableGenMain. +int MlirTblgenMain(int argc, char **argv); +} // namespace mlir + +#endif // MLIR_TOOLS_MLIR_TBLGEN_MLIRTBLGENMAIN_H diff --git a/mlir/lib/TableGen/CMakeLists.txt b/mlir/lib/TableGen/CMakeLists.txt --- a/mlir/lib/TableGen/CMakeLists.txt +++ b/mlir/lib/TableGen/CMakeLists.txt @@ -17,6 +17,7 @@ Constraint.cpp Dialect.cpp Format.cpp + GenInfo.cpp Interfaces.cpp Operator.cpp Pass.cpp diff --git a/mlir/lib/TableGen/GenInfo.cpp b/mlir/lib/TableGen/GenInfo.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/TableGen/GenInfo.cpp @@ -0,0 +1,41 @@ +//===- GenInfo.cpp - Generator info -----------------------------*- 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/TableGen/GenInfo.h" + +#include "mlir/TableGen/GenNameParser.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" + +using namespace mlir; + +static llvm::ManagedStatic> generatorRegistry; + +GenRegistration::GenRegistration(StringRef arg, StringRef description, + const GenFunction &function) { + generatorRegistry->emplace_back(arg, description, function); +} + +GenNameParser::GenNameParser(llvm::cl::Option &opt) + : llvm::cl::parser(opt) { + for (const auto &kv : *generatorRegistry) { + addLiteralOption(kv.getGenArgument(), &kv, kv.getGenDescription()); + } +} + +void GenNameParser::printOptionInfo(const llvm::cl::Option &o, + size_t globalWidth) const { + GenNameParser *tp = const_cast(this); + llvm::array_pod_sort(tp->Values.begin(), tp->Values.end(), + [](const GenNameParser::OptionInfo *vT1, + const GenNameParser::OptionInfo *vT2) { + return vT1->Name.compare(vT2->Name); + }); + using llvm::cl::parser; + parser::printOptionInfo(o, globalWidth); +} diff --git a/mlir/lib/Tools/CMakeLists.txt b/mlir/lib/Tools/CMakeLists.txt --- a/mlir/lib/Tools/CMakeLists.txt +++ b/mlir/lib/Tools/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(mlir-opt) add_subdirectory(mlir-pdll-lsp-server) add_subdirectory(mlir-reduce) +add_subdirectory(mlir-tblgen) add_subdirectory(mlir-translate) add_subdirectory(PDLL) add_subdirectory(tblgen-lsp-server) diff --git a/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt b/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Tools/mlir-tblgen/CMakeLists.txt @@ -0,0 +1,18 @@ +llvm_add_library(MLIRTblgenLib STATIC + MlirTblgenMain.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Tools/mlir-tblgen + + DISABLE_LLVM_LINK_LLVM_DYLIB + + LINK_COMPONENTS + TableGen + + LINK_LIBS PUBLIC + MLIRTableGen + ) + +mlir_check_all_link_libraries(MLIRTblgenLib) + +add_mlir_library_install(MLIRTblgenLib) diff --git a/mlir/tools/mlir-tblgen/mlir-tblgen.cpp b/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp copy from mlir/tools/mlir-tblgen/mlir-tblgen.cpp copy to mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp --- a/mlir/tools/mlir-tblgen/mlir-tblgen.cpp +++ b/mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp @@ -1,4 +1,4 @@ -//===- mlir-tblgen.cpp - Top-Level TableGen implementation for MLIR -------===// +//===- MlirTblgenMain.cpp - MLIR Tablegen Driver main -----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,74 +6,32 @@ // //===----------------------------------------------------------------------===// // -// This file contains the main function for MLIR's TableGen. +// Main entry function for mlir-tblgen for when built as standalone binary. // //===----------------------------------------------------------------------===// +#include "mlir/Tools/mlir-tblgen/MlirTblgenMain.h" + #include "mlir/TableGen/GenInfo.h" #include "mlir/TableGen/GenNameParser.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/InitLLVM.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Signals.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Main.h" #include "llvm/TableGen/Record.h" -#include "llvm/TableGen/TableGenBackend.h" -using namespace llvm; using namespace mlir; +using namespace llvm; enum DeprecatedAction { None, Warn, Error }; -llvm::cl::opt actionOnDeprecated( - "on-deprecated", llvm::cl::init(Warn), - llvm::cl::desc("Action to perform on deprecated def"), - llvm::cl::values(clEnumValN(DeprecatedAction::None, "none", "No action"), - clEnumValN(DeprecatedAction::Warn, "warn", "Warn on use"), - clEnumValN(DeprecatedAction::Error, "error", - "Error on use"))); - -static llvm::ManagedStatic> generatorRegistry; - -mlir::GenRegistration::GenRegistration(StringRef arg, StringRef description, - const GenFunction &function) { - generatorRegistry->emplace_back(arg, description, function); -} - -GenNameParser::GenNameParser(llvm::cl::Option &opt) - : llvm::cl::parser(opt) { - for (const auto &kv : *generatorRegistry) { - addLiteralOption(kv.getGenArgument(), &kv, kv.getGenDescription()); - } -} - -void GenNameParser::printOptionInfo(const llvm::cl::Option &o, - size_t globalWidth) const { - GenNameParser *tp = const_cast(this); - llvm::array_pod_sort(tp->Values.begin(), tp->Values.end(), - [](const GenNameParser::OptionInfo *vT1, - const GenNameParser::OptionInfo *vT2) { - return vT1->Name.compare(vT2->Name); - }); - using llvm::cl::parser; - parser::printOptionInfo(o, globalWidth); -} -// Generator that prints records. -GenRegistration printRecords("print-records", "Print all records to stdout", - [](const RecordKeeper &records, raw_ostream &os) { - os << records; - return false; - }); - -// Generator to invoke. -const mlir::GenInfo *generator; +static DeprecatedAction actionOnDeprecatedValue; // Returns if there is a use of `init` in `record`. -bool findUse(Record &record, Init *init, - llvm::DenseMap &known) { +static bool findUse(Record &record, Init *init, + llvm::DenseMap &known) { auto it = known.find(&record); if (it != known.end()) return it->second; @@ -104,7 +62,7 @@ return memoize(false); } -void warnOfDeprecatedUses(RecordKeeper &records) { +static void warnOfDeprecatedUses(RecordKeeper &records) { // This performs a direct check for any def marked as deprecated and then // finds all uses of deprecated def. Deprecated defs are not expected to be // either numerous or long lived. @@ -135,14 +93,18 @@ } } } - if (deprecatedDefsFounds && actionOnDeprecated == DeprecatedAction::Error) + if (deprecatedDefsFounds && + actionOnDeprecatedValue == DeprecatedAction::Error) PrintFatalNote("Error'ing out due to deprecated defs"); } +// Generator to invoke. +static const mlir::GenInfo *generator; + // TableGenMain requires a function pointer so this function is passed in which // simply wraps the call to the generator. static bool mlirTableGenMain(raw_ostream &os, RecordKeeper &records) { - if (actionOnDeprecated != DeprecatedAction::None) + if (actionOnDeprecatedValue != DeprecatedAction::None) warnOfDeprecatedUses(records); if (!generator) { @@ -152,12 +114,22 @@ return generator->invoke(records, os); } -int main(int argc, char **argv) { +int mlir::MlirTblgenMain(int argc, char **argv) { + llvm::InitLLVM y(argc, argv); - llvm::cl::opt generator( - "", llvm::cl::desc("Generator to run")); + + llvm::cl::opt actionOnDeprecated( + "on-deprecated", llvm::cl::desc("Action to perform on deprecated def"), + llvm::cl::values( + clEnumValN(DeprecatedAction::None, "none", "No action"), + clEnumValN(DeprecatedAction::Warn, "warn", "Warn on use"), + clEnumValN(DeprecatedAction::Error, "error", "Error on use")), + cl::location(actionOnDeprecatedValue), llvm::cl::init(Warn)); + + llvm::cl::opt generator( + "", llvm::cl::desc("Generator to run"), cl::location(::generator)); + cl::ParseCommandLineOptions(argc, argv); - ::generator = generator.getValue(); return TableGenMain(argv[0], &mlirTableGenMain); } diff --git a/mlir/tools/mlir-tblgen/CMakeLists.txt b/mlir/tools/mlir-tblgen/CMakeLists.txt --- a/mlir/tools/mlir-tblgen/CMakeLists.txt +++ b/mlir/tools/mlir-tblgen/CMakeLists.txt @@ -33,6 +33,6 @@ target_link_libraries(mlir-tblgen PRIVATE MLIRSupportIndentedOstream - MLIRTableGen) + MLIRTblgenLib) mlir_check_all_link_libraries(mlir-tblgen) diff --git a/mlir/tools/mlir-tblgen/mlir-tblgen.cpp b/mlir/tools/mlir-tblgen/mlir-tblgen.cpp --- a/mlir/tools/mlir-tblgen/mlir-tblgen.cpp +++ b/mlir/tools/mlir-tblgen/mlir-tblgen.cpp @@ -11,56 +11,12 @@ //===----------------------------------------------------------------------===// #include "mlir/TableGen/GenInfo.h" -#include "mlir/TableGen/GenNameParser.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/InitLLVM.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Signals.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Main.h" +#include "mlir/Tools/mlir-tblgen/MlirTblgenMain.h" #include "llvm/TableGen/Record.h" -#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; using namespace mlir; -enum DeprecatedAction { None, Warn, Error }; -llvm::cl::opt actionOnDeprecated( - "on-deprecated", llvm::cl::init(Warn), - llvm::cl::desc("Action to perform on deprecated def"), - llvm::cl::values(clEnumValN(DeprecatedAction::None, "none", "No action"), - clEnumValN(DeprecatedAction::Warn, "warn", "Warn on use"), - clEnumValN(DeprecatedAction::Error, "error", - "Error on use"))); - -static llvm::ManagedStatic> generatorRegistry; - -mlir::GenRegistration::GenRegistration(StringRef arg, StringRef description, - const GenFunction &function) { - generatorRegistry->emplace_back(arg, description, function); -} - -GenNameParser::GenNameParser(llvm::cl::Option &opt) - : llvm::cl::parser(opt) { - for (const auto &kv : *generatorRegistry) { - addLiteralOption(kv.getGenArgument(), &kv, kv.getGenDescription()); - } -} - -void GenNameParser::printOptionInfo(const llvm::cl::Option &o, - size_t globalWidth) const { - GenNameParser *tp = const_cast(this); - llvm::array_pod_sort(tp->Values.begin(), tp->Values.end(), - [](const GenNameParser::OptionInfo *vT1, - const GenNameParser::OptionInfo *vT2) { - return vT1->Name.compare(vT2->Name); - }); - using llvm::cl::parser; - parser::printOptionInfo(o, globalWidth); -} - // Generator that prints records. GenRegistration printRecords("print-records", "Print all records to stdout", [](const RecordKeeper &records, raw_ostream &os) { @@ -68,96 +24,4 @@ return false; }); -// Generator to invoke. -const mlir::GenInfo *generator; - -// Returns if there is a use of `init` in `record`. -bool findUse(Record &record, Init *init, - llvm::DenseMap &known) { - auto it = known.find(&record); - if (it != known.end()) - return it->second; - - auto memoize = [&](bool val) { - known[&record] = val; - return val; - }; - - for (const RecordVal &val : record.getValues()) { - Init *valInit = val.getValue(); - if (valInit == init) - return true; - if (auto *di = dyn_cast(valInit)) { - if (findUse(*di->getDef(), init, known)) - return memoize(true); - } else if (auto *di = dyn_cast(valInit)) { - for (Init *arg : di->getArgs()) - if (auto *di = dyn_cast(arg)) - if (findUse(*di->getDef(), init, known)) - return memoize(true); - } else if (ListInit *li = dyn_cast(valInit)) { - for (Init *jt : li->getValues()) - if (jt == init) - return memoize(true); - } - } - return memoize(false); -} - -void warnOfDeprecatedUses(RecordKeeper &records) { - // This performs a direct check for any def marked as deprecated and then - // finds all uses of deprecated def. Deprecated defs are not expected to be - // either numerous or long lived. - bool deprecatedDefsFounds = false; - for (auto &it : records.getDefs()) { - const RecordVal *r = it.second->getValue("odsDeprecated"); - if (!r || !r->getValue()) - continue; - - llvm::DenseMap hasUse; - if (auto *si = dyn_cast(r->getValue())) { - for (auto &jt : records.getDefs()) { - // Skip anonymous defs. - if (jt.second->isAnonymous()) - continue; - // Skip all outside main file to avoid flagging redundantly. - unsigned buf = - SrcMgr.FindBufferContainingLoc(jt.second->getLoc().front()); - if (buf != SrcMgr.getMainFileID()) - continue; - - if (findUse(*jt.second, it.second->getDefInit(), hasUse)) { - PrintWarning(jt.second->getLoc(), - "Using deprecated def `" + it.first + "`"); - PrintNote(si->getAsUnquotedString()); - deprecatedDefsFounds = true; - } - } - } - } - if (deprecatedDefsFounds && actionOnDeprecated == DeprecatedAction::Error) - PrintFatalNote("Error'ing out due to deprecated defs"); -} - -// TableGenMain requires a function pointer so this function is passed in which -// simply wraps the call to the generator. -static bool mlirTableGenMain(raw_ostream &os, RecordKeeper &records) { - if (actionOnDeprecated != DeprecatedAction::None) - warnOfDeprecatedUses(records); - - if (!generator) { - os << records; - return false; - } - return generator->invoke(records, os); -} - -int main(int argc, char **argv) { - llvm::InitLLVM y(argc, argv); - llvm::cl::opt generator( - "", llvm::cl::desc("Generator to run")); - cl::ParseCommandLineOptions(argc, argv); - ::generator = generator.getValue(); - - return TableGenMain(argv[0], &mlirTableGenMain); -} +int main(int argc, char **argv) { return MlirTblgenMain(argc, argv); }