Factor out translation registry.

The mlir-translate tool is expected to discover individual translations at link
time.  These translations must register themselves and may need the utilities
that are currently defined in mlir-translate.cpp for their entry point
functions.  Since mlir-translate is linking against individual translations,
the translations cannot link against mlir-translate themselves.  Extract out
the utilities into a separate "Translation" library to avoid the potential
dependency cycle.  Individual translations link to that library to access
TranslateRegistration. The mlir-translate tool links to individual translations
and to the "Translation" library because it needs the utilities as well.

The main header of the new library is located in include/mlir/Translation.h to
make it easily accessible by translators.  The rationale for putting it to
include/mlir rather than to one of its subdirectories is that its purpose is
similar to that of include/mlir/Pass.h so it makes sense to put them at the
same level.

PiperOrigin-RevId: 222398617
This commit is contained in:
Alex Zinenko 2018-11-21 06:21:19 -08:00 committed by jpienaar
parent 1967325244
commit b5756fdaa1
4 changed files with 128 additions and 39 deletions

View File

@ -0,0 +1,54 @@
//===- Translation.h - Translation registry ---------------------*- C++ -*-===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
//
// Registry for user-provided translations.
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_TRANSLATION_H
#define MLIR_TRANSLATION_H
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
namespace mlir {
class MLIRContext;
class Module;
using TranslateFunction =
std::function<bool(llvm::StringRef inputFilename,
llvm::StringRef oututFilename, MLIRContext *)>;
// Use TranslateRegistration as a global initialiser that registers a function
// and associates it with name. This requires that a translation has not been
// registered to a given name.
//
// Usage:
//
// // At namespace scope.
// static TranslateRegistration Unused(&MySubCommand, [] { ... });
//
struct TranslateRegistration {
TranslateRegistration(llvm::StringRef name,
const TranslateFunction &function);
};
/// Get a read-only reference to the translator registry.
const llvm::StringMap<TranslateFunction> &getTranslationRegistry();
} // namespace mlir
#endif // MLIR_TRANSLATION_H

View File

@ -0,0 +1,48 @@
//===- Translation.cpp - Translation registry -------------------*- C++ -*-===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
//
// Definitions of the translation registry.
//
//===----------------------------------------------------------------------===//
#include "mlir/Translation.h"
#include "mlir/Support/LLVM.h"
#include "llvm/Support/ManagedStatic.h"
using namespace mlir;
// Get the mutable static map between translations registered and the
// TranslateFunctions that perform those translations.
static llvm::StringMap<TranslateFunction> &getMutableTranslationRegistry() {
static llvm::StringMap<TranslateFunction> translationRegistry;
return translationRegistry;
}
TranslateRegistration::TranslateRegistration(
StringRef name, const TranslateFunction &function) {
auto &translationRegistry = getMutableTranslationRegistry();
if (translationRegistry.find(name) != translationRegistry.end())
llvm::report_fatal_error("Attempting to overwrite an existing function");
assert(function && "Attempting to register an empty translate function");
translationRegistry[name] = function;
}
// Merely add the const qualifier to the mutable registry so that external users
// cannot modify it.
const llvm::StringMap<TranslateFunction> &mlir::getTranslationRegistry() {
return getMutableTranslationRegistry();
}

View File

@ -24,11 +24,11 @@
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"
#include "mlir/Parser.h"
#include "mlir/Translation.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
@ -57,17 +57,26 @@ Module *mlir::parseMLIRInput(StringRef inputFilename, MLIRContext *context) {
return parseSourceFile(sourceMgr, context);
}
bool mlir::printMLIROutput(const Module &module,
llvm::StringRef outputFilename) {
std::unique_ptr<llvm::ToolOutputFile>
mlir::openOutputFile(llvm::StringRef outputFilename) {
std::error_code error;
auto result = llvm::make_unique<llvm::ToolOutputFile>(outputFilename, error,
llvm::sys::fs::F_None);
if (error) {
llvm::errs() << error.message();
return true;
return nullptr;
}
module.print(result->os());
result->keep();
return result;
}
bool mlir::printMLIROutput(const Module &module,
llvm::StringRef outputFilename) {
auto file = openOutputFile(outputFilename);
if (!file)
return true;
module.print(file->os());
file->keep();
return false;
}
@ -83,24 +92,11 @@ static TranslateRegistration MLIRToMLIRTranslate(
return printMLIROutput(*module, outputFilename);
});
// Static map between translations registered and the TranslateFunctions that
// perform those translations.
static llvm::ManagedStatic<llvm::StringMap<TranslateFunction>>
translationRegistry;
TranslateRegistration::TranslateRegistration(
llvm::StringRef name, const TranslateFunction &function) {
if (translationRegistry->find(name) != translationRegistry->end())
llvm::report_fatal_error("Attempting to overwrite an existing function");
assert(function && "Attempting to register an empty translate function");
(*translationRegistry)[name] = function;
}
// Custom parser for TranslateFunction.
struct TranslationParser : public llvm::cl::parser<const TranslateFunction *> {
TranslationParser(llvm::cl::Option &opt)
: llvm::cl::parser<const TranslateFunction *>(opt) {
for (const auto &kv : *translationRegistry) {
for (const auto &kv : getTranslationRegistry()) {
addLiteralOption(kv.first(), &kv.second, kv.first());
}
}

View File

@ -1,4 +1,4 @@
//===- mlir-translate.h - Registry & utility functions for translations ---===//
//===- mlir-translate.h - Translation driver -----------------*- C++ -*----===//
//
// Copyright 2019 The MLIR Authors.
//
@ -22,29 +22,20 @@
#ifndef TOOLS_MLIR_TRANSLATE_H
#define TOOLS_MLIR_TRANSLATE_H
#include "llvm/ADT/StringRef.h"
#include "mlir/Support/LLVM.h"
#include <memory>
namespace llvm {
class ToolOutputFile;
}
namespace mlir {
class MLIRContext;
class Module;
using TranslateFunction =
std::function<bool(llvm::StringRef inputFilename,
llvm::StringRef oututFilename, MLIRContext *)>;
// Use TranslateRegistration as a global initialiser that registers a function
// and associates it with name. This requires that a translation has not been
// registered to a given name.
//
// Usage:
//
// // At namespace scope.
// static TranslateRegistration Unused(&MySubCommand, [] { ... });
//
struct TranslateRegistration {
TranslateRegistration(llvm::StringRef name,
const TranslateFunction &function);
};
/// Open a file to be used as raw_ostream.
std::unique_ptr<llvm::ToolOutputFile>
openOutputFile(llvm::StringRef outputFilename);
// Returns module parsed from input filename or null in case of error.
Module *parseMLIRInput(llvm::StringRef inputFilename, MLIRContext *context);