Files
clang-p2996/mlir/tools/mlir-tblgen/PassCAPIGen.cpp
Mehdi Amini dc43f78565 Add basic Python bindings for the PassManager and bind libTransforms
This only exposes the ability to round-trip a textual pipeline at the
moment.
To exercise it, we also bind the libTransforms in a new Python extension. This
does not include any interesting bindings, but it includes all the
mechanism to add separate native extensions and load them dynamically.
As such passes in libTransforms are only registered after `import
mlir.transforms`.
To support this global registration, the TableGen backend is also
extended to bind to the C API the group registration for passes.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D90819
2020-11-10 19:55:21 +00:00

113 lines
3.5 KiB
C++

//===- Pass.cpp - MLIR pass registration generator ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// PassCAPIGen uses the description of passes to generate C API for the passes.
//
//===----------------------------------------------------------------------===//
#include "mlir/TableGen/GenInfo.h"
#include "mlir/TableGen/Pass.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
using namespace mlir;
using namespace mlir::tblgen;
static llvm::cl::OptionCategory
passGenCat("Options for -gen-pass-capi-header and -gen-pass-capi-impl");
static llvm::cl::opt<std::string>
groupName("prefix",
llvm::cl::desc("The prefix to use for this group of passes. The "
"form will be mlirCreate<prefix><passname>, the "
"prefix can avoid conflicts across libraries."),
llvm::cl::cat(passGenCat));
const char *const passDecl = R"(
/* Create {0} Pass. */
MLIR_CAPI_EXPORTED MlirPass mlirCreate{0}{1}();
MLIR_CAPI_EXPORTED void mlirRegister{0}{1}();
)";
const char *const fileHeader = R"(
/* Autogenerated by mlir-tblgen; don't manually edit. */
#include "mlir-c/Pass.h"
#ifdef __cplusplus
extern "C" {
#endif
)";
const char *const fileFooter = R"(
#ifdef __cplusplus
}
#endif
)";
/// Emit TODO
static bool emitCAPIHeader(const llvm::RecordKeeper &records, raw_ostream &os) {
os << fileHeader;
os << "// Registration for the entire group\n";
os << "MLIR_CAPI_EXPORTED void mlirRegister" << groupName << "Passes();\n\n";
for (const auto *def : records.getAllDerivedDefinitions("PassBase")) {
Pass pass(def);
StringRef defName = pass.getDef()->getName();
os << llvm::formatv(passDecl, groupName, defName);
}
os << fileFooter;
return false;
}
const char *const passCreateDef = R"(
MlirPass mlirCreate{0}{1}() {
return wrap({2}.release());
}
void mlirRegister{0}{1}() {
register{1}Pass();
}
)";
/// {0}: The name of the pass group.
const char *const passGroupRegistrationCode = R"(
//===----------------------------------------------------------------------===//
// {0} Group Registration
//===----------------------------------------------------------------------===//
void mlirRegister{0}Passes() {{
register{0}Passes();
}
)";
static bool emitCAPIImpl(const llvm::RecordKeeper &records, raw_ostream &os) {
os << "/* Autogenerated by mlir-tblgen; don't manually edit. */";
os << llvm::formatv(passGroupRegistrationCode, groupName);
for (const auto *def : records.getAllDerivedDefinitions("PassBase")) {
Pass pass(def);
StringRef defName = pass.getDef()->getName();
os << llvm::formatv(passCreateDef, groupName, defName,
pass.getConstructor());
}
return false;
}
static mlir::GenRegistration genCAPIHeader("gen-pass-capi-header",
"Generate pass C API header",
&emitCAPIHeader);
static mlir::GenRegistration genCAPIImpl("gen-pass-capi-impl",
"Generate pass C API implementation",
&emitCAPIImpl);