[bug] The additional patch committed file was deleted.
authorchangkaiyan <894076259@qq.com>
Tue, 4 Oct 2022 02:16:08 +0000 (10:16 +0800)
committerchangkaiyan <894076259@qq.com>
Tue, 4 Oct 2022 02:19:59 +0000 (10:19 +0800)
Differential Revision: https://reviews.llvm.org/D134696

deleted:    202209301111.patch

202209301111.patch [deleted file]

diff --git a/202209301111.patch b/202209301111.patch
deleted file mode 100644 (file)
index 27da882..0000000
+++ /dev/null
@@ -1,2050 +0,0 @@
-diff --git a/mlir/examples/standalone/standalone-translate/standalone-translate.cpp b/mlir/examples/standalone/standalone-translate/standalone-translate.cpp
-index 2c2f275..31ddef4 100644
---- a/mlir/examples/standalone/standalone-translate/standalone-translate.cpp
-+++ b/mlir/examples/standalone/standalone-translate/standalone-translate.cpp
-@@ -1,27 +1,34 @@
- //===- standalone-translate.cpp ---------------------------------*- C++ -*-===//
- //
- // This file is licensed 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 a file from/to MLIR using one
- // of the registered translations.
- //
- //===----------------------------------------------------------------------===//
-+#include "Standalone/StandaloneDialect.h"
-+#include "mlir/IR/BuiltinOps.h"
- #include "mlir/InitAllTranslations.h"
- #include "mlir/Support/LogicalResult.h"
- #include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
--
--#include "Standalone/StandaloneDialect.h"
-+#include "mlir/Tools/mlir-translate/Translation.h"
- int main(int argc, char **argv) {
-   mlir::registerAllTranslations();
-   // TODO: Register standalone translations here.
-+  mlir::TranslateFromMLIRRegistration withdescription(
-+      "option", "different from option",
-+      [](mlir::ModuleOp op, llvm::raw_ostream &output) {
-+        return mlir::LogicalResult::success();
-+      },
-+      [](mlir::DialectRegistry &a) {});
-   return failed(
-       mlir::mlirTranslateMain(argc, argv, "MLIR Translation Testing Tool"));
- }
-diff --git a/mlir/include/mlir/Tools/mlir-translate/Translation.h b/mlir/include/mlir/Tools/mlir-translate/Translation.h
-index d91e479..c8b5b70 100644
---- a/mlir/include/mlir/Tools/mlir-translate/Translation.h
-+++ b/mlir/include/mlir/Tools/mlir-translate/Translation.h
-@@ -1,102 +1,103 @@
- //===- Translation.h - Translation registry ---------------------*- 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
- //
- //===----------------------------------------------------------------------===//
- //
- // Registry for user-provided translations.
- //
- //===----------------------------------------------------------------------===//
- #ifndef MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H
- #define MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H
- #include "llvm/Support/CommandLine.h"
- namespace llvm {
- class MemoryBuffer;
- class SourceMgr;
- class StringRef;
- } // namespace llvm
- namespace mlir {
- class DialectRegistry;
- struct LogicalResult;
- class MLIRContext;
- class ModuleOp;
- template <typename OpTy>
- class OwningOpRef;
- /// Interface of the function that translates the sources managed by `sourceMgr`
- /// to MLIR. The source manager has at least one buffer. The implementation
- /// should create a new MLIR ModuleOp in the given context and return a pointer
- /// to it, or a nullptr in case of any error.
- using TranslateSourceMgrToMLIRFunction = std::function<OwningOpRef<ModuleOp>(
-     llvm::SourceMgr &sourceMgr, MLIRContext *)>;
- /// Interface of the function that translates the given string to MLIR. The
- /// implementation should create a new MLIR ModuleOp in the given context. If
- /// source-related error reporting is required from within the function, use
- /// TranslateSourceMgrToMLIRFunction instead.
- using TranslateStringRefToMLIRFunction =
-     std::function<OwningOpRef<ModuleOp>(llvm::StringRef, MLIRContext *)>;
- /// Interface of the function that translates MLIR to a different format and
- /// outputs the result to a stream. It is allowed to modify the module.
- using TranslateFromMLIRFunction =
-     std::function<LogicalResult(ModuleOp, llvm::raw_ostream &output)>;
- /// Interface of the function that performs file-to-file translation involving
- /// MLIR. The input file is held in the given MemoryBuffer; the output file
- /// should be written to the given raw_ostream. The implementation should create
- /// all MLIR constructs needed during the process inside the given context. This
- /// can be used for round-tripping external formats through the MLIR system.
- using TranslateFunction = std::function<LogicalResult(
-     llvm::SourceMgr &sourceMgr, llvm::raw_ostream &output, MLIRContext *)>;
- /// Use Translate[ToMLIR|FromMLIR]Registration as an initializer that
- /// registers a function and associates it with name. This requires that a
- /// translation has not been registered to a given name.
- ///
- /// Usage:
- ///
- ///   // At file scope.
- ///   namespace mlir {
- ///   void registerTRexToMLIRRegistration() {
- ///     TranslateToMLIRRegistration Unused(&MySubCommand, [] { ... });
- ///   }
- ///   } // namespace mlir
- ///
- /// \{
- struct TranslateToMLIRRegistration {
--  TranslateToMLIRRegistration(llvm::StringRef name,
-+  TranslateToMLIRRegistration(llvm::StringRef name, llvm::StringRef description,
-                               const TranslateSourceMgrToMLIRFunction &function);
--  TranslateToMLIRRegistration(llvm::StringRef name,
-+  TranslateToMLIRRegistration(llvm::StringRef name, llvm::StringRef description,
-                               const TranslateStringRefToMLIRFunction &function);
- };
- struct TranslateFromMLIRRegistration {
-   TranslateFromMLIRRegistration(
--      llvm::StringRef name, const TranslateFromMLIRFunction &function,
-+      llvm::StringRef name, llvm::StringRef description,
-+      const TranslateFromMLIRFunction &function,
-       const std::function<void(DialectRegistry &)> &dialectRegistration =
-           [](DialectRegistry &) {});
- };
- struct TranslateRegistration {
--  TranslateRegistration(llvm::StringRef name,
-+  TranslateRegistration(llvm::StringRef name, llvm::StringRef description,
-                         const TranslateFunction &function);
- };
- /// \}
- /// A command line parser for translation functions.
- struct TranslationParser : public llvm::cl::parser<const TranslateFunction *> {
-   TranslationParser(llvm::cl::Option &opt);
-   void printOptionInfo(const llvm::cl::Option &o,
-                        size_t globalWidth) const override;
- };
- } // namespace mlir
- #endif // MLIR_TOOLS_MLIRTRANSLATE_TRANSLATION_H
-# diff --git a/mlir/lib/Target/Cpp/TranslateRegistration.cpp b/mlir/lib/Target/Cpp/TranslateRegistration.cpp
-# index c4d26ea..c85dd0d 100644
-# --- a/mlir/lib/Target/Cpp/TranslateRegistration.cpp
-# +++ b/mlir/lib/Target/Cpp/TranslateRegistration.cpp
-# @@ -1,54 +1,54 @@
-#  //===- TranslateRegistration.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/Dialect/Arithmetic/IR/Arithmetic.h"
-#  #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h"
-#  #include "mlir/Dialect/EmitC/IR/EmitC.h"
-#  #include "mlir/Dialect/Func/IR/FuncOps.h"
-#  #include "mlir/Dialect/Math/IR/Math.h"
-#  #include "mlir/Dialect/SCF/IR/SCF.h"
-#  #include "mlir/IR/BuiltinOps.h"
-#  #include "mlir/IR/Dialect.h"
-#  #include "mlir/Target/Cpp/CppEmitter.h"
-#  #include "mlir/Tools/mlir-translate/Translation.h"
-#  #include "llvm/Support/CommandLine.h"
-#  using namespace mlir;
-#  namespace mlir {
-#  //===----------------------------------------------------------------------===//
-#  // Cpp registration
-#  //===----------------------------------------------------------------------===//
-#  void registerToCppTranslation() {
-#    static llvm::cl::opt<bool> declareVariablesAtTop(
-#        "declare-variables-at-top",
-#        llvm::cl::desc("Declare variables at top when emitting C/C++"),
-#        llvm::cl::init(false));
-#    TranslateFromMLIRRegistration reg(
-# -      "mlir-to-cpp",
-# +      "mlir-to-cpp", "translate mlir to cpp",
-#        [](ModuleOp module, raw_ostream &output) {
-#          return emitc::translateToCpp(
-#              module, output,
-#              /*declareVariablesAtTop=*/declareVariablesAtTop);
-#        },
-#        [](DialectRegistry &registry) {
-#          // clang-format off
-#          registry.insert<arith::ArithmeticDialect,
-#                          cf::ControlFlowDialect,
-#                          emitc::EmitCDialect,
-#                          func::FuncDialect,
-#                          math::MathDialect,
-#                          scf::SCFDialect>();
-#          // clang-format on
-#        });
-#  }
-#  } // namespace mlir
-# diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
-# index 9c47d36..b839bba 100644
-# --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
-# +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
-# @@ -1,1415 +1,1416 @@
-#  //===- ConvertFromLLVMIR.cpp - MLIR to LLVM IR conversion -----------------===//
-#  //
-#  // 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 implements a translation between LLVM IR and the MLIR LLVM dialect.
-#  //
-#  //===----------------------------------------------------------------------===//
-#  #include "mlir/Target/LLVMIR/Import.h"
-#  #include "mlir/Dialect/DLTI/DLTI.h"
-#  #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
-#  #include "mlir/IR/Builders.h"
-#  #include "mlir/IR/BuiltinOps.h"
-#  #include "mlir/IR/BuiltinTypes.h"
-#  #include "mlir/IR/MLIRContext.h"
-#  #include "mlir/Interfaces/DataLayoutInterfaces.h"
-#  #include "mlir/Target/LLVMIR/TypeFromLLVM.h"
-#  #include "mlir/Tools/mlir-translate/Translation.h"
-#  #include "llvm/ADT/StringSet.h"
-#  #include "llvm/ADT/TypeSwitch.h"
-#  #include "llvm/IR/Attributes.h"
-#  #include "llvm/IR/Constants.h"
-#  #include "llvm/IR/DerivedTypes.h"
-#  #include "llvm/IR/Function.h"
-#  #include "llvm/IR/InlineAsm.h"
-#  #include "llvm/IR/Instructions.h"
-#  #include "llvm/IR/Intrinsics.h"
-#  #include "llvm/IR/Type.h"
-#  #include "llvm/IRReader/IRReader.h"
-#  #include "llvm/Support/Error.h"
-#  #include "llvm/Support/SourceMgr.h"
-#  using namespace mlir;
-#  using namespace mlir::LLVM;
-#  #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
-#  // Utility to print an LLVM value as a string for passing to emitError().
-#  // FIXME: Diagnostic should be able to natively handle types that have
-#  // operator << (raw_ostream&) defined.
-#  static std::string diag(llvm::Value &v) {
-#    std::string s;
-#    llvm::raw_string_ostream os(s);
-#    os << v;
-#    return os.str();
-#  }
-#  /// Creates an attribute containing ABI and preferred alignment numbers parsed
-#  /// a string. The string may be either "abi:preferred" or just "abi". In the
-#  /// latter case, the prefrred alignment is considered equal to ABI alignment.
-#  static DenseIntElementsAttr parseDataLayoutAlignment(MLIRContext &ctx,
-#                                                       StringRef spec) {
-#    auto i32 = IntegerType::get(&ctx, 32);
-#    StringRef abiString, preferredString;
-#    std::tie(abiString, preferredString) = spec.split(':');
-#    int abi, preferred;
-#    if (abiString.getAsInteger(/*Radix=*/10, abi))
-#      return nullptr;
-#    if (preferredString.empty())
-#      preferred = abi;
-#    else if (preferredString.getAsInteger(/*Radix=*/10, preferred))
-#      return nullptr;
-#    return DenseIntElementsAttr::get(VectorType::get({2}, i32), {abi, preferred});
-#  }
-#  /// Returns a supported MLIR floating point type of the given bit width or null
-#  /// if the bit width is not supported.
-#  static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth) {
-#    switch (bitwidth) {
-#    case 16:
-#      return FloatType::getF16(&ctx);
-#    case 32:
-#      return FloatType::getF32(&ctx);
-#    case 64:
-#      return FloatType::getF64(&ctx);
-#    case 80:
-#      return FloatType::getF80(&ctx);
-#    case 128:
-#      return FloatType::getF128(&ctx);
-#    default:
-#      return nullptr;
-#    }
-#  }
-#  DataLayoutSpecInterface
-#  mlir::translateDataLayout(const llvm::DataLayout &dataLayout,
-#                            MLIRContext *context) {
-#    assert(context && "expected MLIR context");
-#    std::string layoutstr = dataLayout.getStringRepresentation();
-#    // Remaining unhandled default layout defaults
-#    // e (little endian if not set)
-#    // p[n]:64:64:64 (non zero address spaces have 64-bit properties)
-#    std::string append =
-#        "p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f64:"
-#        "64:64-f128:128:128-v64:64:64-v128:128:128-a:0:64";
-#    if (layoutstr.empty())
-#      layoutstr = append;
-#    else
-#      layoutstr = layoutstr + "-" + append;
-#    StringRef layout(layoutstr);
-#    SmallVector<DataLayoutEntryInterface> entries;
-#    StringSet<> seen;
-#    while (!layout.empty()) {
-#      // Split at '-'.
-#      std::pair<StringRef, StringRef> split = layout.split('-');
-#      StringRef current;
-#      std::tie(current, layout) = split;
-#      // Split at ':'.
-#      StringRef kind, spec;
-#      std::tie(kind, spec) = current.split(':');
-#      if (seen.contains(kind))
-#        continue;
-#      seen.insert(kind);
-#      char symbol = kind.front();
-#      StringRef parameter = kind.substr(1);
-#      if (symbol == 'i' || symbol == 'f') {
-#        unsigned bitwidth;
-#        if (parameter.getAsInteger(/*Radix=*/10, bitwidth))
-#          return nullptr;
-#        DenseIntElementsAttr params = parseDataLayoutAlignment(*context, spec);
-#        if (!params)
-#          return nullptr;
-#        auto entry = DataLayoutEntryAttr::get(
-#            symbol == 'i' ? static_cast<Type>(IntegerType::get(context, bitwidth))
-#                          : getDLFloatType(*context, bitwidth),
-#            params);
-#        entries.emplace_back(entry);
-#      } else if (symbol == 'e' || symbol == 'E') {
-#        auto value = StringAttr::get(
-#            context, symbol == 'e' ? DLTIDialect::kDataLayoutEndiannessLittle
-#                                   : DLTIDialect::kDataLayoutEndiannessBig);
-#        auto entry = DataLayoutEntryAttr::get(
-#            StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey),
-#            value);
-#        entries.emplace_back(entry);
-#      }
-#    }
-#    return DataLayoutSpecAttr::get(context, entries);
-#  }
-#  // Handles importing globals and functions from an LLVM module.
-#  namespace {
-#  class Importer {
-#  public:
-#    Importer(MLIRContext *context, ModuleOp module)
-#        : b(context), context(context), module(module),
-#          unknownLoc(FileLineColLoc::get(context, "imported-bitcode", 0, 0)),
-#          typeTranslator(*context) {
-#      b.setInsertionPointToStart(module.getBody());
-#    }
-#    /// Imports `f` into the current module.
-#    LogicalResult processFunction(llvm::Function *f);
-#    /// Converts function attributes of LLVM Function \p f
-#    /// into LLVM dialect attributes of LLVMFuncOp \p funcOp.
-#    void processFunctionAttributes(llvm::Function *f, LLVMFuncOp funcOp);
-#    /// Imports GV as a GlobalOp, creating it if it doesn't exist.
-#    GlobalOp processGlobal(llvm::GlobalVariable *gv);
-#  private:
-#    /// Returns personality of `f` as a FlatSymbolRefAttr.
-#    FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *f);
-#    /// Imports `bb` into `block`, which must be initially empty.
-#    LogicalResult processBasicBlock(llvm::BasicBlock *bb, Block *block);
-#    /// Imports `inst` and populates instMap[inst] with the imported Value.
-#    LogicalResult processInstruction(llvm::Instruction *inst);
-#    /// Creates an LLVM-compatible MLIR type for `type`.
-#    Type processType(llvm::Type *type);
-#    /// `value` is an SSA-use. Return the remapped version of `value` or a
-#    /// placeholder that will be remapped later if this is an instruction that
-#    /// has not yet been visited.
-#    Value processValue(llvm::Value *value);
-#    /// Create the most accurate Location possible using a llvm::DebugLoc and
-#    /// possibly an llvm::Instruction to narrow the Location if debug information
-#    /// is unavailable.
-#    Location processDebugLoc(const llvm::DebugLoc &loc,
-#                             llvm::Instruction *inst = nullptr);
-#    /// `br` branches to `target`. Append the block arguments to attach to the
-#    /// generated branch op to `blockArguments`. These should be in the same order
-#    /// as the PHIs in `target`.
-#    LogicalResult processBranchArgs(llvm::Instruction *br,
-#                                    llvm::BasicBlock *target,
-#                                    SmallVectorImpl<Value> &blockArguments);
-#    /// Returns the builtin type equivalent to be used in attributes for the given
-#    /// LLVM IR dialect type.
-#    Type getStdTypeForAttr(Type type);
-#    /// Return `value` as an attribute to attach to a GlobalOp.
-#    Attribute getConstantAsAttr(llvm::Constant *value);
-#    /// Return `c` as an MLIR Value. This could either be a ConstantOp, or
-#    /// an expanded sequence of ops in the current function's entry block (for
-#    /// ConstantExprs or ConstantGEPs).
-#    Value processConstant(llvm::Constant *c);
-#    /// The current builder, pointing at where the next Instruction should be
-#    /// generated.
-#    OpBuilder b;
-#    /// The current context.
-#    MLIRContext *context;
-#    /// The current module being created.
-#    ModuleOp module;
-#    /// The entry block of the current function being processed.
-#    Block *currentEntryBlock = nullptr;
-#    /// Globals are inserted before the first function, if any.
-#    Block::iterator getGlobalInsertPt() {
-#      auto it = module.getBody()->begin();
-#      auto endIt = module.getBody()->end();
-#      while (it != endIt && !isa<LLVMFuncOp>(it))
-#        ++it;
-#      return it;
-#    }
-#    /// Functions are always inserted before the module terminator.
-#    Block::iterator getFuncInsertPt() {
-#      return std::prev(module.getBody()->end());
-#    }
-#    /// Remapped blocks, for the current function.
-#    DenseMap<llvm::BasicBlock *, Block *> blocks;
-#    /// Remapped values. These are function-local.
-#    DenseMap<llvm::Value *, Value> instMap;
-#    /// Instructions that had not been defined when first encountered as a use.
-#    /// Maps to the dummy Operation that was created in processValue().
-#    DenseMap<llvm::Value *, Operation *> unknownInstMap;
-#    /// Uniquing map of GlobalVariables.
-#    DenseMap<llvm::GlobalVariable *, GlobalOp> globals;
-#    /// Cached FileLineColLoc::get("imported-bitcode", 0, 0).
-#    Location unknownLoc;
-#    /// The stateful type translator (contains named structs).
-#    LLVM::TypeFromLLVMIRTranslator typeTranslator;
-#  };
-#  } // namespace
-#  Location Importer::processDebugLoc(const llvm::DebugLoc &loc,
-#                                     llvm::Instruction *inst) {
-#    if (!loc)
-#      return unknownLoc;
-#    // FIXME: Obtain the filename from DILocationInfo.
-#    return FileLineColLoc::get(context, "imported-bitcode", loc.getLine(),
-#                               loc.getCol());
-#  }
-#  Type Importer::processType(llvm::Type *type) {
-#    if (Type result = typeTranslator.translateType(type))
-#      return result;
-#    // FIXME: Diagnostic should be able to natively handle types that have
-#    // operator<<(raw_ostream&) defined.
-#    std::string s;
-#    llvm::raw_string_ostream os(s);
-#    os << *type;
-#    emitError(unknownLoc) << "unhandled type: " << os.str();
-#    return nullptr;
-#  }
-#  // We only need integers, floats, doubles, and vectors and tensors thereof for
-#  // attributes. Scalar and vector types are converted to the standard
-#  // equivalents. Array types are converted to ranked tensors; nested array types
-#  // are converted to multi-dimensional tensors or vectors, depending on the
-#  // innermost type being a scalar or a vector.
-#  Type Importer::getStdTypeForAttr(Type type) {
-#    if (!type)
-#      return nullptr;
-#    if (type.isa<IntegerType, FloatType>())
-#      return type;
-#    // LLVM vectors can only contain scalars.
-#    if (LLVM::isCompatibleVectorType(type)) {
-#      auto numElements = LLVM::getVectorNumElements(type);
-#      if (numElements.isScalable()) {
-#        emitError(unknownLoc) << "scalable vectors not supported";
-#        return nullptr;
-#      }
-#      Type elementType = getStdTypeForAttr(LLVM::getVectorElementType(type));
-#      if (!elementType)
-#        return nullptr;
-#      return VectorType::get(numElements.getKnownMinValue(), elementType);
-#    }
-#    // LLVM arrays can contain other arrays or vectors.
-#    if (auto arrayType = type.dyn_cast<LLVMArrayType>()) {
-#      // Recover the nested array shape.
-#      SmallVector<int64_t, 4> shape;
-#      shape.push_back(arrayType.getNumElements());
-#      while (arrayType.getElementType().isa<LLVMArrayType>()) {
-#        arrayType = arrayType.getElementType().cast<LLVMArrayType>();
-#        shape.push_back(arrayType.getNumElements());
-#      }
-#      // If the innermost type is a vector, use the multi-dimensional vector as
-#      // attribute type.
-#      if (LLVM::isCompatibleVectorType(arrayType.getElementType())) {
-#        auto numElements = LLVM::getVectorNumElements(arrayType.getElementType());
-#        if (numElements.isScalable()) {
-#          emitError(unknownLoc) << "scalable vectors not supported";
-#          return nullptr;
-#        }
-#        shape.push_back(numElements.getKnownMinValue());
-#        Type elementType = getStdTypeForAttr(
-#            LLVM::getVectorElementType(arrayType.getElementType()));
-#        if (!elementType)
-#          return nullptr;
-#        return VectorType::get(shape, elementType);
-#      }
-#      // Otherwise use a tensor.
-#      Type elementType = getStdTypeForAttr(arrayType.getElementType());
-#      if (!elementType)
-#        return nullptr;
-#      return RankedTensorType::get(shape, elementType);
-#    }
-#    return nullptr;
-#  }
-#  // Get the given constant as an attribute. Not all constants can be represented
-#  // as attributes.
-#  Attribute Importer::getConstantAsAttr(llvm::Constant *value) {
-#    if (auto *ci = dyn_cast<llvm::ConstantInt>(value))
-#      return b.getIntegerAttr(
-#          IntegerType::get(context, ci->getType()->getBitWidth()),
-#          ci->getValue());
-#    if (auto *c = dyn_cast<llvm::ConstantDataArray>(value))
-#      if (c->isString())
-#        return b.getStringAttr(c->getAsString());
-#    if (auto *c = dyn_cast<llvm::ConstantFP>(value)) {
-#      auto *type = c->getType();
-#      FloatType floatTy;
-#      if (type->isBFloatTy())
-#        floatTy = FloatType::getBF16(context);
-#      else
-#        floatTy = getDLFloatType(*context, type->getScalarSizeInBits());
-#      assert(floatTy && "unsupported floating point type");
-#      return b.getFloatAttr(floatTy, c->getValueAPF());
-#    }
-#    if (auto *f = dyn_cast<llvm::Function>(value))
-#      return SymbolRefAttr::get(b.getContext(), f->getName());
-#    // Convert constant data to a dense elements attribute.
-#    if (auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) {
-#      Type type = processType(cd->getElementType());
-#      if (!type)
-#        return nullptr;
-#      auto attrType = getStdTypeForAttr(processType(cd->getType()))
-#                          .dyn_cast_or_null<ShapedType>();
-#      if (!attrType)
-#        return nullptr;
-#      if (type.isa<IntegerType>()) {
-#        SmallVector<APInt, 8> values;
-#        values.reserve(cd->getNumElements());
-#        for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
-#          values.push_back(cd->getElementAsAPInt(i));
-#        return DenseElementsAttr::get(attrType, values);
-#      }
-#      if (type.isa<Float32Type, Float64Type>()) {
-#        SmallVector<APFloat, 8> values;
-#        values.reserve(cd->getNumElements());
-#        for (unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
-#          values.push_back(cd->getElementAsAPFloat(i));
-#        return DenseElementsAttr::get(attrType, values);
-#      }
-#      return nullptr;
-#    }
-#    // Unpack constant aggregates to create dense elements attribute whenever
-#    // possible. Return nullptr (failure) otherwise.
-#    if (isa<llvm::ConstantAggregate>(value)) {
-#      auto outerType = getStdTypeForAttr(processType(value->getType()))
-#                           .dyn_cast_or_null<ShapedType>();
-#      if (!outerType)
-#        return nullptr;
-#      SmallVector<Attribute, 8> values;
-#      SmallVector<int64_t, 8> shape;
-#      for (unsigned i = 0, e = value->getNumOperands(); i < e; ++i) {
-#        auto nested = getConstantAsAttr(value->getAggregateElement(i))
-#                          .dyn_cast_or_null<DenseElementsAttr>();
-#        if (!nested)
-#          return nullptr;
-#        values.append(nested.value_begin<Attribute>(),
-#                      nested.value_end<Attribute>());
-#      }
-#      return DenseElementsAttr::get(outerType, values);
-#    }
-#    return nullptr;
-#  }
-#  GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
-#    auto it = globals.find(gv);
-#    if (it != globals.end())
-#      return it->second;
-#    OpBuilder b(module.getBody(), getGlobalInsertPt());
-#    Attribute valueAttr;
-#    if (gv->hasInitializer())
-#      valueAttr = getConstantAsAttr(gv->getInitializer());
-#    Type type = processType(gv->getValueType());
-#    if (!type)
-#      return nullptr;
-#    uint64_t alignment = 0;
-#    llvm::MaybeAlign maybeAlign = gv->getAlign();
-#    if (maybeAlign.has_value()) {
-#      llvm::Align align = maybeAlign.value();
-#      alignment = align.value();
-#    }
-#    GlobalOp op = b.create<GlobalOp>(
-#        UnknownLoc::get(context), type, gv->isConstant(),
-#        convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr,
-#        alignment, /*addr_space=*/gv->getAddressSpace(),
-#        /*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal());
-#    if (gv->hasInitializer() && !valueAttr) {
-#      Region &r = op.getInitializerRegion();
-#      currentEntryBlock = b.createBlock(&r);
-#      b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
-#      Value v = processConstant(gv->getInitializer());
-#      if (!v)
-#        return nullptr;
-#      b.create<ReturnOp>(op.getLoc(), ArrayRef<Value>({v}));
-#    }
-#    if (gv->hasAtLeastLocalUnnamedAddr())
-#      op.setUnnamedAddrAttr(UnnamedAddrAttr::get(
-#          context, convertUnnamedAddrFromLLVM(gv->getUnnamedAddr())));
-#    if (gv->hasSection())
-#      op.setSectionAttr(b.getStringAttr(gv->getSection()));
-#    return globals[gv] = op;
-#  }
-#  Value Importer::processConstant(llvm::Constant *c) {
-#    OpBuilder bEntry(currentEntryBlock, currentEntryBlock->begin());
-#    if (Attribute attr = getConstantAsAttr(c)) {
-#      // These constants can be represented as attributes.
-#      OpBuilder b(currentEntryBlock, currentEntryBlock->begin());
-#      Type type = processType(c->getType());
-#      if (!type)
-#        return nullptr;
-#      if (auto symbolRef = attr.dyn_cast<FlatSymbolRefAttr>())
-#        return bEntry.create<AddressOfOp>(unknownLoc, type, symbolRef.getValue());
-#      return bEntry.create<ConstantOp>(unknownLoc, type, attr);
-#    }
-#    if (auto *cn = dyn_cast<llvm::ConstantPointerNull>(c)) {
-#      Type type = processType(cn->getType());
-#      if (!type)
-#        return nullptr;
-#      return bEntry.create<NullOp>(unknownLoc, type);
-#    }
-#    if (auto *gv = dyn_cast<llvm::GlobalVariable>(c))
-#      return bEntry.create<AddressOfOp>(UnknownLoc::get(context),
-#                                        processGlobal(gv));
-#    if (auto *ce = dyn_cast<llvm::ConstantExpr>(c)) {
-#      llvm::Instruction *i = ce->getAsInstruction();
-#      OpBuilder::InsertionGuard guard(b);
-#      b.setInsertionPoint(currentEntryBlock, currentEntryBlock->begin());
-#      if (failed(processInstruction(i)))
-#        return nullptr;
-#      assert(instMap.count(i));
-#      // If we don't remove entry of `i` here, it's totally possible that the
-#      // next time llvm::ConstantExpr::getAsInstruction is called again, which
-#      // always allocates a new Instruction, memory address of the newly
-#      // created Instruction might be the same as `i`. Making processInstruction
-#      // falsely believe that the new Instruction has been processed before
-#      // and raised an assertion error.
-#      Value value = instMap[i];
-#      instMap.erase(i);
-#      // Remove this zombie LLVM instruction now, leaving us only with the MLIR
-#      // op.
-#      i->deleteValue();
-#      return value;
-#    }
-#    if (auto *ue = dyn_cast<llvm::UndefValue>(c)) {
-#      Type type = processType(ue->getType());
-#      if (!type)
-#        return nullptr;
-#      return bEntry.create<UndefOp>(UnknownLoc::get(context), type);
-#    }
-#    if (isa<llvm::ConstantAggregate>(c) || isa<llvm::ConstantAggregateZero>(c)) {
-#      unsigned numElements = c->getNumOperands();
-#      std::function<llvm::Constant *(unsigned)> getElement =
-#          [&](unsigned index) -> llvm::Constant * {
-#        return c->getAggregateElement(index);
-#      };
-#      // llvm::ConstantAggregateZero doesn't take any operand
-#      // so its getNumOperands is always zero.
-#      if (auto *caz = dyn_cast<llvm::ConstantAggregateZero>(c)) {
-#        numElements = caz->getElementCount().getFixedValue();
-#        // We want to capture the pointer rather than reference
-#        // to the pointer since the latter will become dangling upon
-#        // exiting the scope.
-#        getElement = [=](unsigned index) -> llvm::Constant * {
-#          return caz->getElementValue(index);
-#        };
-#      }
-#      // Generate a llvm.undef as the root value first.
-#      Type rootType = processType(c->getType());
-#      if (!rootType)
-#        return nullptr;
-#      bool useInsertValue = rootType.isa<LLVMArrayType, LLVMStructType>();
-#      assert((useInsertValue || LLVM::isCompatibleVectorType(rootType)) &&
-#             "unrecognized aggregate type");
-#      Value root = bEntry.create<UndefOp>(unknownLoc, rootType);
-#      for (unsigned i = 0; i < numElements; ++i) {
-#        llvm::Constant *element = getElement(i);
-#        Value elementValue = processConstant(element);
-#        if (!elementValue)
-#          return nullptr;
-#        if (useInsertValue) {
-#          root = bEntry.create<InsertValueOp>(UnknownLoc::get(context), root,
-#                                              elementValue, i);
-#        } else {
-#          Attribute indexAttr = bEntry.getI32IntegerAttr(static_cast<int32_t>(i));
-#          Value indexValue = bEntry.create<ConstantOp>(
-#              unknownLoc, bEntry.getI32Type(), indexAttr);
-#          if (!indexValue)
-#            return nullptr;
-#          root = bEntry.create<InsertElementOp>(
-#              UnknownLoc::get(context), rootType, root, elementValue, indexValue);
-#        }
-#      }
-#      return root;
-#    }
-#    emitError(unknownLoc) << "unhandled constant: " << diag(*c);
-#    return nullptr;
-#  }
-#  Value Importer::processValue(llvm::Value *value) {
-#    auto it = instMap.find(value);
-#    if (it != instMap.end())
-#      return it->second;
-#    // We don't expect to see instructions in dominator order. If we haven't seen
-#    // this instruction yet, create an unknown op and remap it later.
-#    if (isa<llvm::Instruction>(value)) {
-#      Type type = processType(value->getType());
-#      if (!type)
-#        return nullptr;
-#      unknownInstMap[value] =
-#          b.create(UnknownLoc::get(context), b.getStringAttr("llvm.unknown"),
-#                   /*operands=*/{}, type);
-#      return unknownInstMap[value]->getResult(0);
-#    }
-#    if (auto *c = dyn_cast<llvm::Constant>(value))
-#      return processConstant(c);
-#    emitError(unknownLoc) << "unhandled value: " << diag(*value);
-#    return nullptr;
-#  }
-#  /// Return the MLIR OperationName for the given LLVM opcode.
-#  static StringRef lookupOperationNameFromOpcode(unsigned opcode) {
-#  // Maps from LLVM opcode to MLIR OperationName. This is deliberately ordered
-#  // as in llvm/IR/Instructions.def to aid comprehension and spot missing
-#  // instructions.
-#  #define INST(llvm_n, mlir_n)                                                   \
-#    { llvm::Instruction::llvm_n, LLVM::mlir_n##Op::getOperationName() }
-#    static const DenseMap<unsigned, StringRef> opcMap = {
-#        // clang-format off
-#        INST(Ret, Return),
-#        // Br is handled specially.
-#        // Switch is handled specially.
-#        // FIXME: indirectbr
-#        // Invoke is handled specially.
-#        INST(Resume, Resume),
-#        INST(Unreachable, Unreachable),
-#        // FIXME: cleanupret
-#        // FIXME: catchret
-#        // FIXME: catchswitch
-#        // FIXME: callbr
-#        INST(FNeg, FNeg),
-#        INST(Add, Add),
-#        INST(FAdd, FAdd),
-#        INST(Sub, Sub),
-#        INST(FSub, FSub),
-#        INST(Mul, Mul),
-#        INST(FMul, FMul),
-#        INST(UDiv, UDiv),
-#        INST(SDiv, SDiv),
-#        INST(FDiv, FDiv),
-#        INST(URem, URem),
-#        INST(SRem, SRem),
-#        INST(FRem, FRem),
-#        INST(Shl, Shl),
-#        INST(LShr, LShr),
-#        INST(AShr, AShr),
-#        INST(And, And),
-#        INST(Or, Or),
-#        INST(Xor, XOr),
-#        INST(ExtractElement, ExtractElement),
-#        INST(InsertElement, InsertElement),
-#        // ShuffleVector is handled specially.
-#        // ExtractValue is handled specially.
-#        // InsertValue is handled specially.
-#        INST(Alloca, Alloca),
-#        INST(Load, Load),
-#        INST(Store, Store),
-#        INST(Fence, Fence),
-#        // AtomicCmpXchg is handled specially.
-#        // AtomicRMW is handled specially.
-#        // Getelementptr is handled specially.
-#        INST(Trunc, Trunc),
-#        INST(ZExt, ZExt),
-#        INST(SExt, SExt),
-#        INST(FPToUI, FPToUI),
-#        INST(FPToSI, FPToSI),
-#        INST(UIToFP, UIToFP),
-#        INST(SIToFP, SIToFP),
-#        INST(FPTrunc, FPTrunc),
-#        INST(FPExt, FPExt),
-#        INST(PtrToInt, PtrToInt),
-#        INST(IntToPtr, IntToPtr),
-#        INST(BitCast, Bitcast),
-#        INST(AddrSpaceCast, AddrSpaceCast),
-#        // ICmp is handled specially.
-#        // FCmp is handled specially.
-#        // PHI is handled specially.
-#        INST(Select, Select),
-#        INST(Freeze, Freeze),
-#        INST(Call, Call),
-#        // FIXME: vaarg
-#        // FIXME: landingpad
-#        // FIXME: catchpad
-#        // FIXME: cleanuppad
-#        // clang-format on
-#    };
-#  #undef INST
-#    return opcMap.lookup(opcode);
-#  }
-#  /// Return the MLIR OperationName for the given LLVM intrinsic ID.
-#  static StringRef lookupOperationNameFromIntrinsicID(unsigned id) {
-#    // Maps from LLVM intrinsic ID to MLIR OperationName.
-#    static const DenseMap<unsigned, StringRef> intrMap = {
-#  #include "mlir/Dialect/LLVMIR/LLVMIntrinsicToLLVMIROpPairs.inc"
-#    };
-#    return intrMap.lookup(id);
-#  }
-#  static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) {
-#    switch (p) {
-#    default:
-#      llvm_unreachable("incorrect comparison predicate");
-#    case llvm::CmpInst::Predicate::ICMP_EQ:
-#      return LLVM::ICmpPredicate::eq;
-#    case llvm::CmpInst::Predicate::ICMP_NE:
-#      return LLVM::ICmpPredicate::ne;
-#    case llvm::CmpInst::Predicate::ICMP_SLT:
-#      return LLVM::ICmpPredicate::slt;
-#    case llvm::CmpInst::Predicate::ICMP_SLE:
-#      return LLVM::ICmpPredicate::sle;
-#    case llvm::CmpInst::Predicate::ICMP_SGT:
-#      return LLVM::ICmpPredicate::sgt;
-#    case llvm::CmpInst::Predicate::ICMP_SGE:
-#      return LLVM::ICmpPredicate::sge;
-#    case llvm::CmpInst::Predicate::ICMP_ULT:
-#      return LLVM::ICmpPredicate::ult;
-#    case llvm::CmpInst::Predicate::ICMP_ULE:
-#      return LLVM::ICmpPredicate::ule;
-#    case llvm::CmpInst::Predicate::ICMP_UGT:
-#      return LLVM::ICmpPredicate::ugt;
-#    case llvm::CmpInst::Predicate::ICMP_UGE:
-#      return LLVM::ICmpPredicate::uge;
-#    }
-#    llvm_unreachable("incorrect integer comparison predicate");
-#  }
-#  static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate p) {
-#    switch (p) {
-#    default:
-#      llvm_unreachable("incorrect comparison predicate");
-#    case llvm::CmpInst::Predicate::FCMP_FALSE:
-#      return LLVM::FCmpPredicate::_false;
-#    case llvm::CmpInst::Predicate::FCMP_TRUE:
-#      return LLVM::FCmpPredicate::_true;
-#    case llvm::CmpInst::Predicate::FCMP_OEQ:
-#      return LLVM::FCmpPredicate::oeq;
-#    case llvm::CmpInst::Predicate::FCMP_ONE:
-#      return LLVM::FCmpPredicate::one;
-#    case llvm::CmpInst::Predicate::FCMP_OLT:
-#      return LLVM::FCmpPredicate::olt;
-#    case llvm::CmpInst::Predicate::FCMP_OLE:
-#      return LLVM::FCmpPredicate::ole;
-#    case llvm::CmpInst::Predicate::FCMP_OGT:
-#      return LLVM::FCmpPredicate::ogt;
-#    case llvm::CmpInst::Predicate::FCMP_OGE:
-#      return LLVM::FCmpPredicate::oge;
-#    case llvm::CmpInst::Predicate::FCMP_ORD:
-#      return LLVM::FCmpPredicate::ord;
-#    case llvm::CmpInst::Predicate::FCMP_ULT:
-#      return LLVM::FCmpPredicate::ult;
-#    case llvm::CmpInst::Predicate::FCMP_ULE:
-#      return LLVM::FCmpPredicate::ule;
-#    case llvm::CmpInst::Predicate::FCMP_UGT:
-#      return LLVM::FCmpPredicate::ugt;
-#    case llvm::CmpInst::Predicate::FCMP_UGE:
-#      return LLVM::FCmpPredicate::uge;
-#    case llvm::CmpInst::Predicate::FCMP_UNO:
-#      return LLVM::FCmpPredicate::uno;
-#    case llvm::CmpInst::Predicate::FCMP_UEQ:
-#      return LLVM::FCmpPredicate::ueq;
-#    case llvm::CmpInst::Predicate::FCMP_UNE:
-#      return LLVM::FCmpPredicate::une;
-#    }
-#    llvm_unreachable("incorrect floating point comparison predicate");
-#  }
-#  static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering) {
-#    switch (ordering) {
-#    case llvm::AtomicOrdering::NotAtomic:
-#      return LLVM::AtomicOrdering::not_atomic;
-#    case llvm::AtomicOrdering::Unordered:
-#      return LLVM::AtomicOrdering::unordered;
-#    case llvm::AtomicOrdering::Monotonic:
-#      return LLVM::AtomicOrdering::monotonic;
-#    case llvm::AtomicOrdering::Acquire:
-#      return LLVM::AtomicOrdering::acquire;
-#    case llvm::AtomicOrdering::Release:
-#      return LLVM::AtomicOrdering::release;
-#    case llvm::AtomicOrdering::AcquireRelease:
-#      return LLVM::AtomicOrdering::acq_rel;
-#    case llvm::AtomicOrdering::SequentiallyConsistent:
-#      return LLVM::AtomicOrdering::seq_cst;
-#    }
-#    llvm_unreachable("incorrect atomic ordering");
-#  }
-#  static AtomicBinOp getLLVMAtomicBinOp(llvm::AtomicRMWInst::BinOp binOp) {
-#    switch (binOp) {
-#    case llvm::AtomicRMWInst::Xchg:
-#      return LLVM::AtomicBinOp::xchg;
-#    case llvm::AtomicRMWInst::Add:
-#      return LLVM::AtomicBinOp::add;
-#    case llvm::AtomicRMWInst::Sub:
-#      return LLVM::AtomicBinOp::sub;
-#    case llvm::AtomicRMWInst::And:
-#      return LLVM::AtomicBinOp::_and;
-#    case llvm::AtomicRMWInst::Nand:
-#      return LLVM::AtomicBinOp::nand;
-#    case llvm::AtomicRMWInst::Or:
-#      return LLVM::AtomicBinOp::_or;
-#    case llvm::AtomicRMWInst::Xor:
-#      return LLVM::AtomicBinOp::_xor;
-#    case llvm::AtomicRMWInst::Max:
-#      return LLVM::AtomicBinOp::max;
-#    case llvm::AtomicRMWInst::Min:
-#      return LLVM::AtomicBinOp::min;
-#    case llvm::AtomicRMWInst::UMax:
-#      return LLVM::AtomicBinOp::umax;
-#    case llvm::AtomicRMWInst::UMin:
-#      return LLVM::AtomicBinOp::umin;
-#    case llvm::AtomicRMWInst::FAdd:
-#      return LLVM::AtomicBinOp::fadd;
-#    case llvm::AtomicRMWInst::FSub:
-#      return LLVM::AtomicBinOp::fsub;
-#    default:
-#      llvm_unreachable("unsupported atomic binary operation");
-#    }
-#  }
-#  // `br` branches to `target`. Return the branch arguments to `br`, in the
-#  // same order of the PHIs in `target`.
-#  LogicalResult
-#  Importer::processBranchArgs(llvm::Instruction *br, llvm::BasicBlock *target,
-#                              SmallVectorImpl<Value> &blockArguments) {
-#    for (auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
-#      auto *pn = cast<llvm::PHINode>(&*inst);
-#      Value value = processValue(pn->getIncomingValueForBlock(br->getParent()));
-#      if (!value)
-#        return failure();
-#      blockArguments.push_back(value);
-#    }
-#    return success();
-#  }
-#  LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
-#    // FIXME: Support uses of SubtargetData. Currently inbounds GEPs, fast-math
-#    // flags and call / operand attributes are not supported.
-#    Location loc = processDebugLoc(inst->getDebugLoc(), inst);
-#    assert(!instMap.count(inst) &&
-#           "processInstruction must be called only once per instruction!");
-#    switch (inst->getOpcode()) {
-#    default:
-#      return emitError(loc) << "unknown instruction: " << diag(*inst);
-#    case llvm::Instruction::Add:
-#    case llvm::Instruction::FAdd:
-#    case llvm::Instruction::Sub:
-#    case llvm::Instruction::FSub:
-#    case llvm::Instruction::Mul:
-#    case llvm::Instruction::FMul:
-#    case llvm::Instruction::UDiv:
-#    case llvm::Instruction::SDiv:
-#    case llvm::Instruction::FDiv:
-#    case llvm::Instruction::URem:
-#    case llvm::Instruction::SRem:
-#    case llvm::Instruction::FRem:
-#    case llvm::Instruction::Shl:
-#    case llvm::Instruction::LShr:
-#    case llvm::Instruction::AShr:
-#    case llvm::Instruction::And:
-#    case llvm::Instruction::Or:
-#    case llvm::Instruction::Xor:
-#    case llvm::Instruction::Load:
-#    case llvm::Instruction::Store:
-#    case llvm::Instruction::Ret:
-#    case llvm::Instruction::Resume:
-#    case llvm::Instruction::Trunc:
-#    case llvm::Instruction::ZExt:
-#    case llvm::Instruction::SExt:
-#    case llvm::Instruction::FPToUI:
-#    case llvm::Instruction::FPToSI:
-#    case llvm::Instruction::UIToFP:
-#    case llvm::Instruction::SIToFP:
-#    case llvm::Instruction::FPTrunc:
-#    case llvm::Instruction::FPExt:
-#    case llvm::Instruction::PtrToInt:
-#    case llvm::Instruction::IntToPtr:
-#    case llvm::Instruction::AddrSpaceCast:
-#    case llvm::Instruction::Freeze:
-#    case llvm::Instruction::BitCast:
-#    case llvm::Instruction::ExtractElement:
-#    case llvm::Instruction::InsertElement:
-#    case llvm::Instruction::Select:
-#    case llvm::Instruction::FNeg:
-#    case llvm::Instruction::Unreachable: {
-#      OperationState state(loc, lookupOperationNameFromOpcode(inst->getOpcode()));
-#      SmallVector<Value, 4> ops;
-#      ops.reserve(inst->getNumOperands());
-#      for (auto *op : inst->operand_values()) {
-#        Value value = processValue(op);
-#        if (!value)
-#          return failure();
-#        ops.push_back(value);
-#      }
-#      state.addOperands(ops);
-#      if (!inst->getType()->isVoidTy()) {
-#        Type type = processType(inst->getType());
-#        if (!type)
-#          return failure();
-#        state.addTypes(type);
-#      }
-#      Operation *op = b.create(state);
-#      if (!inst->getType()->isVoidTy())
-#        instMap[inst] = op->getResult(0);
-#      return success();
-#    }
-#    case llvm::Instruction::Alloca: {
-#      Value size = processValue(inst->getOperand(0));
-#      if (!size)
-#        return failure();
-#      auto *allocaInst = cast<llvm::AllocaInst>(inst);
-#      instMap[inst] =
-#          b.create<AllocaOp>(loc, processType(inst->getType()),
-#                             processType(allocaInst->getAllocatedType()), size,
-#                             allocaInst->getAlign().value());
-#      return success();
-#    }
-#    case llvm::Instruction::ICmp: {
-#      Value lhs = processValue(inst->getOperand(0));
-#      Value rhs = processValue(inst->getOperand(1));
-#      if (!lhs || !rhs)
-#        return failure();
-#      instMap[inst] = b.create<ICmpOp>(
-#          loc, getICmpPredicate(cast<llvm::ICmpInst>(inst)->getPredicate()), lhs,
-#          rhs);
-#      return success();
-#    }
-#    case llvm::Instruction::FCmp: {
-#      Value lhs = processValue(inst->getOperand(0));
-#      Value rhs = processValue(inst->getOperand(1));
-#      if (!lhs || !rhs)
-#        return failure();
-#      if (lhs.getType() != rhs.getType())
-#        return failure();
-#      Type boolType = b.getI1Type();
-#      Type resType = boolType;
-#      if (LLVM::isCompatibleVectorType(lhs.getType())) {
-#        unsigned numElements =
-#            LLVM::getVectorNumElements(lhs.getType()).getFixedValue();
-#        resType = VectorType::get({numElements}, boolType);
-#      }
-#      instMap[inst] = b.create<FCmpOp>(
-#          loc, resType,
-#          getFCmpPredicate(cast<llvm::FCmpInst>(inst)->getPredicate()), lhs, rhs);
-#      return success();
-#    }
-#    case llvm::Instruction::Br: {
-#      auto *brInst = cast<llvm::BranchInst>(inst);
-#      OperationState state(loc,
-#                           brInst->isConditional() ? "llvm.cond_br" : "llvm.br");
-#      if (brInst->isConditional()) {
-#        Value condition = processValue(brInst->getCondition());
-#        if (!condition)
-#          return failure();
-#        state.addOperands(condition);
-#      }
-#      std::array<int32_t, 3> operandSegmentSizes = {1, 0, 0};
-#      for (int i : llvm::seq<int>(0, brInst->getNumSuccessors())) {
-#        auto *succ = brInst->getSuccessor(i);
-#        SmallVector<Value, 4> blockArguments;
-#        if (failed(processBranchArgs(brInst, succ, blockArguments)))
-#          return failure();
-#        state.addSuccessors(blocks[succ]);
-#        state.addOperands(blockArguments);
-#        operandSegmentSizes[i + 1] = blockArguments.size();
-#      }
-#      if (brInst->isConditional()) {
-#        state.addAttribute(LLVM::CondBrOp::getOperandSegmentSizeAttr(),
-#                           b.getDenseI32ArrayAttr(operandSegmentSizes));
-#      }
-#      b.create(state);
-#      return success();
-#    }
-#    case llvm::Instruction::Switch: {
-#      auto *swInst = cast<llvm::SwitchInst>(inst);
-#      // Process the condition value.
-#      Value condition = processValue(swInst->getCondition());
-#      if (!condition)
-#        return failure();
-#      SmallVector<Value> defaultBlockArgs;
-#      // Process the default case.
-#      llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
-#      if (failed(processBranchArgs(swInst, defaultBB, defaultBlockArgs)))
-#        return failure();
-#      // Process the cases.
-#      unsigned numCases = swInst->getNumCases();
-#      SmallVector<SmallVector<Value>> caseOperands(numCases);
-#      SmallVector<ValueRange> caseOperandRefs(numCases);
-#      SmallVector<int32_t> caseValues(numCases);
-#      SmallVector<Block *> caseBlocks(numCases);
-#      for (const auto &en : llvm::enumerate(swInst->cases())) {
-#        const llvm::SwitchInst::CaseHandle &caseHandle = en.value();
-#        unsigned i = en.index();
-#        llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
-#        if (failed(processBranchArgs(swInst, succBB, caseOperands[i])))
-#          return failure();
-#        caseOperandRefs[i] = caseOperands[i];
-#        caseValues[i] = caseHandle.getCaseValue()->getSExtValue();
-#        caseBlocks[i] = blocks[succBB];
-#      }
-#      b.create<SwitchOp>(loc, condition, blocks[defaultBB], defaultBlockArgs,
-#                         caseValues, caseBlocks, caseOperandRefs);
-#      return success();
-#    }
-#    case llvm::Instruction::PHI: {
-#      Type type = processType(inst->getType());
-#      if (!type)
-#        return failure();
-#      instMap[inst] = b.getInsertionBlock()->addArgument(
-#          type, processDebugLoc(inst->getDebugLoc(), inst));
-#      return success();
-#    }
-#    case llvm::Instruction::Call: {
-#      llvm::CallInst *ci = cast<llvm::CallInst>(inst);
-#      SmallVector<Value, 4> ops;
-#      ops.reserve(inst->getNumOperands());
-#      for (auto &op : ci->args()) {
-#        Value arg = processValue(op.get());
-#        if (!arg)
-#          return failure();
-#        ops.push_back(arg);
-#      }
-#      SmallVector<Type, 2> tys;
-#      if (!ci->getType()->isVoidTy()) {
-#        Type type = processType(inst->getType());
-#        if (!type)
-#          return failure();
-#        tys.push_back(type);
-#      }
-#      Operation *op;
-#      if (llvm::Function *callee = ci->getCalledFunction()) {
-#        // For all intrinsics, try to generate to the corresponding op.
-#        if (callee->isIntrinsic()) {
-#          auto id = callee->getIntrinsicID();
-#          StringRef opName = lookupOperationNameFromIntrinsicID(id);
-#          if (!opName.empty()) {
-#            OperationState state(loc, opName);
-#            state.addOperands(ops);
-#            state.addTypes(tys);
-#            Operation *op = b.create(state);
-#            if (!inst->getType()->isVoidTy())
-#              instMap[inst] = op->getResult(0);
-#            return success();
-#          }
-#        }
-#        op = b.create<CallOp>(
-#            loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops);
-#      } else {
-#        Value calledValue = processValue(ci->getCalledOperand());
-#        if (!calledValue)
-#          return failure();
-#        ops.insert(ops.begin(), calledValue);
-#        op = b.create<CallOp>(loc, tys, ops);
-#      }
-#      if (!ci->getType()->isVoidTy())
-#        instMap[inst] = op->getResult(0);
-#      return success();
-#    }
-#    case llvm::Instruction::LandingPad: {
-#      llvm::LandingPadInst *lpi = cast<llvm::LandingPadInst>(inst);
-#      SmallVector<Value, 4> ops;
-#      for (unsigned i = 0, ie = lpi->getNumClauses(); i < ie; i++)
-#        ops.push_back(processConstant(lpi->getClause(i)));
-#      Type ty = processType(lpi->getType());
-#      if (!ty)
-#        return failure();
-#      instMap[inst] = b.create<LandingpadOp>(loc, ty, lpi->isCleanup(), ops);
-#      return success();
-#    }
-#    case llvm::Instruction::Invoke: {
-#      llvm::InvokeInst *ii = cast<llvm::InvokeInst>(inst);
-#      SmallVector<Type, 2> tys;
-#      if (!ii->getType()->isVoidTy())
-#        tys.push_back(processType(inst->getType()));
-#      SmallVector<Value, 4> ops;
-#      ops.reserve(inst->getNumOperands() + 1);
-#      for (auto &op : ii->args())
-#        ops.push_back(processValue(op.get()));
-#      SmallVector<Value, 4> normalArgs, unwindArgs;
-#      (void)processBranchArgs(ii, ii->getNormalDest(), normalArgs);
-#      (void)processBranchArgs(ii, ii->getUnwindDest(), unwindArgs);
-#      Operation *op;
-#      if (llvm::Function *callee = ii->getCalledFunction()) {
-#        op = b.create<InvokeOp>(
-#            loc, tys, SymbolRefAttr::get(b.getContext(), callee->getName()), ops,
-#            blocks[ii->getNormalDest()], normalArgs, blocks[ii->getUnwindDest()],
-#            unwindArgs);
-#      } else {
-#        ops.insert(ops.begin(), processValue(ii->getCalledOperand()));
-#        op = b.create<InvokeOp>(loc, tys, ops, blocks[ii->getNormalDest()],
-#                                normalArgs, blocks[ii->getUnwindDest()],
-#                                unwindArgs);
-#      }
-#      if (!ii->getType()->isVoidTy())
-#        instMap[inst] = op->getResult(0);
-#      return success();
-#    }
-#    case llvm::Instruction::Fence: {
-#      StringRef syncscope;
-#      SmallVector<StringRef, 4> ssNs;
-#      llvm::LLVMContext &llvmContext = inst->getContext();
-#      llvm::FenceInst *fence = cast<llvm::FenceInst>(inst);
-#      llvmContext.getSyncScopeNames(ssNs);
-#      int fenceSyncScopeID = fence->getSyncScopeID();
-#      for (unsigned i = 0, e = ssNs.size(); i != e; i++) {
-#        if (fenceSyncScopeID == llvmContext.getOrInsertSyncScopeID(ssNs[i])) {
-#          syncscope = ssNs[i];
-#          break;
-#        }
-#      }
-#      b.create<FenceOp>(loc, getLLVMAtomicOrdering(fence->getOrdering()),
-#                        syncscope);
-#      return success();
-#    }
-#    case llvm::Instruction::AtomicRMW: {
-#      auto *atomicInst = cast<llvm::AtomicRMWInst>(inst);
-#      Value ptr = processValue(atomicInst->getPointerOperand());
-#      Value val = processValue(atomicInst->getValOperand());
-#      if (!ptr || !val)
-#        return failure();
-#      LLVM::AtomicBinOp binOp = getLLVMAtomicBinOp(atomicInst->getOperation());
-#      LLVM::AtomicOrdering ordering =
-#          getLLVMAtomicOrdering(atomicInst->getOrdering());
-#      Type type = processType(inst->getType());
-#      if (!type)
-#        return failure();
-#      instMap[inst] = b.create<AtomicRMWOp>(loc, type, binOp, ptr, val, ordering);
-#      return success();
-#    }
-#    case llvm::Instruction::AtomicCmpXchg: {
-#      auto *cmpXchgInst = cast<llvm::AtomicCmpXchgInst>(inst);
-#      Value ptr = processValue(cmpXchgInst->getPointerOperand());
-#      Value cmpVal = processValue(cmpXchgInst->getCompareOperand());
-#      Value newVal = processValue(cmpXchgInst->getNewValOperand());
-#      if (!ptr || !cmpVal || !newVal)
-#        return failure();
-#      LLVM::AtomicOrdering ordering =
-#          getLLVMAtomicOrdering(cmpXchgInst->getSuccessOrdering());
-#      LLVM::AtomicOrdering failOrdering =
-#          getLLVMAtomicOrdering(cmpXchgInst->getFailureOrdering());
-#      Type type = processType(inst->getType());
-#      if (!type)
-#        return failure();
-#      instMap[inst] = b.create<AtomicCmpXchgOp>(loc, type, ptr, cmpVal, newVal,
-#                                                ordering, failOrdering);
-#      return success();
-#    }
-#    case llvm::Instruction::GetElementPtr: {
-#      // FIXME: Support inbounds GEPs.
-#      llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst);
-#      Value basePtr = processValue(gep->getOperand(0));
-#      Type sourceElementType = processType(gep->getSourceElementType());
-#      // Treat every indices as dynamic since GEPOp::build will refine those
-#      // indices into static attributes later. One small downside of this
-#      // approach is that many unused `llvm.mlir.constant` would be emitted
-#      // at first place.
-#      SmallVector<GEPArg> indices;
-#      for (llvm::Value *operand : llvm::drop_begin(gep->operand_values())) {
-#        Value val = processValue(operand);
-#        if (!val)
-#          return failure();
-#        indices.push_back(val);
-#      }
-#      Type type = processType(inst->getType());
-#      if (!type)
-#        return failure();
-#      instMap[inst] =
-#          b.create<GEPOp>(loc, type, sourceElementType, basePtr, indices);
-#      return success();
-#    }
-#    case llvm::Instruction::InsertValue: {
-#      auto *ivInst = cast<llvm::InsertValueInst>(inst);
-#      Value inserted = processValue(ivInst->getInsertedValueOperand());
-#      if (!inserted)
-#        return failure();
-#      Value aggOperand = processValue(ivInst->getAggregateOperand());
-#      if (!aggOperand)
-#        return failure();
-#      SmallVector<int64_t> indices;
-#      llvm::append_range(indices, ivInst->getIndices());
-#      instMap[inst] = b.create<InsertValueOp>(loc, aggOperand, inserted, indices);
-#      return success();
-#    }
-#    case llvm::Instruction::ExtractValue: {
-#      auto *evInst = cast<llvm::ExtractValueInst>(inst);
-#      Value aggOperand = processValue(evInst->getAggregateOperand());
-#      if (!aggOperand)
-#        return failure();
-#      Type type = processType(inst->getType());
-#      if (!type)
-#        return failure();
-#      SmallVector<int64_t> indices;
-#      llvm::append_range(indices, evInst->getIndices());
-#      instMap[inst] = b.create<ExtractValueOp>(loc, aggOperand, indices);
-#      return success();
-#    }
-#    case llvm::Instruction::ShuffleVector: {
-#      auto *svInst = cast<llvm::ShuffleVectorInst>(inst);
-#      Value vec1 = processValue(svInst->getOperand(0));
-#      if (!vec1)
-#        return failure();
-#      Value vec2 = processValue(svInst->getOperand(1));
-#      if (!vec2)
-#        return failure();
-#      SmallVector<int32_t> mask(svInst->getShuffleMask());
-#      instMap[inst] = b.create<ShuffleVectorOp>(loc, vec1, vec2, mask);
-#      return success();
-#    }
-#    }
-#  }
-#  FlatSymbolRefAttr Importer::getPersonalityAsAttr(llvm::Function *f) {
-#    if (!f->hasPersonalityFn())
-#      return nullptr;
-#    llvm::Constant *pf = f->getPersonalityFn();
-#    // If it directly has a name, we can use it.
-#    if (pf->hasName())
-#      return SymbolRefAttr::get(b.getContext(), pf->getName());
-#    // If it doesn't have a name, currently, only function pointers that are
-#    // bitcast to i8* are parsed.
-#    if (auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
-#      if (ce->getOpcode() == llvm::Instruction::BitCast &&
-#          ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) {
-#        if (auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
-#          return SymbolRefAttr::get(b.getContext(), func->getName());
-#      }
-#    }
-#    return FlatSymbolRefAttr();
-#  }
-#  void Importer::processFunctionAttributes(llvm::Function *func,
-#                                           LLVMFuncOp funcOp) {
-#    auto addNamedUnitAttr = [&](StringRef name) {
-#      return funcOp->setAttr(name, UnitAttr::get(context));
-#    };
-#    if (func->hasFnAttribute(llvm::Attribute::ReadNone))
-#      addNamedUnitAttr(LLVMDialect::getReadnoneAttrName());
-#  }
-#  LogicalResult Importer::processFunction(llvm::Function *f) {
-#    blocks.clear();
-#    instMap.clear();
-#    unknownInstMap.clear();
-#    auto functionType =
-#        processType(f->getFunctionType()).dyn_cast<LLVMFunctionType>();
-#    if (!functionType)
-#      return failure();
-#    if (f->isIntrinsic()) {
-#      StringRef opName = lookupOperationNameFromIntrinsicID(f->getIntrinsicID());
-#      // Skip the intrinsic decleration if we could found a corresponding op.
-#      if (!opName.empty())
-#        return success();
-#    }
-#    bool dsoLocal = f->hasLocalLinkage();
-#    CConv cconv = convertCConvFromLLVM(f->getCallingConv());
-#    b.setInsertionPoint(module.getBody(), getFuncInsertPt());
-#    LLVMFuncOp fop = b.create<LLVMFuncOp>(
-#        UnknownLoc::get(context), f->getName(), functionType,
-#        convertLinkageFromLLVM(f->getLinkage()), dsoLocal, cconv);
-#    for (const auto &arg : llvm::enumerate(functionType.getParams())) {
-#      llvm::SmallVector<NamedAttribute, 1> argAttrs;
-#      if (auto *type = f->getParamByValType(arg.index())) {
-#        auto mlirType = processType(type);
-#        argAttrs.push_back(
-#            NamedAttribute(b.getStringAttr(LLVMDialect::getByValAttrName()),
-#                           TypeAttr::get(mlirType)));
-#      }
-#      if (auto *type = f->getParamByRefType(arg.index())) {
-#        auto mlirType = processType(type);
-#        argAttrs.push_back(
-#            NamedAttribute(b.getStringAttr(LLVMDialect::getByRefAttrName()),
-#                           TypeAttr::get(mlirType)));
-#      }
-#      if (auto *type = f->getParamStructRetType(arg.index())) {
-#        auto mlirType = processType(type);
-#        argAttrs.push_back(
-#            NamedAttribute(b.getStringAttr(LLVMDialect::getStructRetAttrName()),
-#                           TypeAttr::get(mlirType)));
-#      }
-#      if (auto *type = f->getParamInAllocaType(arg.index())) {
-#        auto mlirType = processType(type);
-#        argAttrs.push_back(
-#            NamedAttribute(b.getStringAttr(LLVMDialect::getInAllocaAttrName()),
-#                           TypeAttr::get(mlirType)));
-#      }
-#      fop.setArgAttrs(arg.index(), argAttrs);
-#    }
-#    if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f))
-#      fop->setAttr(b.getStringAttr("personality"), personality);
-#    else if (f->hasPersonalityFn())
-#      emitWarning(UnknownLoc::get(context),
-#                  "could not deduce personality, skipping it");
-#    if (f->hasGC())
-#      fop.setGarbageCollectorAttr(b.getStringAttr(f->getGC()));
-#    // Handle Function attributes.
-#    processFunctionAttributes(f, fop);
-#    if (f->isDeclaration())
-#      return success();
-#    // Eagerly create all blocks.
-#    SmallVector<Block *, 4> blockList;
-#    for (llvm::BasicBlock &bb : *f) {
-#      blockList.push_back(b.createBlock(&fop.getBody(), fop.getBody().end()));
-#      blocks[&bb] = blockList.back();
-#    }
-#    currentEntryBlock = blockList[0];
-#    // Add function arguments to the entry block.
-#    for (const auto &kv : llvm::enumerate(f->args())) {
-#      instMap[&kv.value()] = blockList[0]->addArgument(
-#          functionType.getParamType(kv.index()), fop.getLoc());
-#    }
-#    for (auto bbs : llvm::zip(*f, blockList)) {
-#      if (failed(processBasicBlock(&std::get<0>(bbs), std::get<1>(bbs))))
-#        return failure();
-#    }
-#    // Now that all instructions are guaranteed to have been visited, ensure
-#    // any unknown uses we encountered are remapped.
-#    for (auto &llvmAndUnknown : unknownInstMap) {
-#      assert(instMap.count(llvmAndUnknown.first));
-#      Value newValue = instMap[llvmAndUnknown.first];
-#      Value oldValue = llvmAndUnknown.second->getResult(0);
-#      oldValue.replaceAllUsesWith(newValue);
-#      llvmAndUnknown.second->erase();
-#    }
-#    return success();
-#  }
-#  LogicalResult Importer::processBasicBlock(llvm::BasicBlock *bb, Block *block) {
-#    b.setInsertionPointToStart(block);
-#    for (llvm::Instruction &inst : *bb) {
-#      if (failed(processInstruction(&inst)))
-#        return failure();
-#    }
-#    return success();
-#  }
-#  OwningOpRef<ModuleOp>
-#  mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
-#                                MLIRContext *context) {
-#    context->loadDialect<LLVMDialect>();
-#    context->loadDialect<DLTIDialect>();
-#    OwningOpRef<ModuleOp> module(ModuleOp::create(
-#        FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0)));
-#    DataLayoutSpecInterface dlSpec =
-#        translateDataLayout(llvmModule->getDataLayout(), context);
-#    if (!dlSpec) {
-#      emitError(UnknownLoc::get(context), "can't translate data layout");
-#      return {};
-#    }
-#    module.get()->setAttr(DLTIDialect::kDataLayoutAttrName, dlSpec);
-#    Importer deserializer(context, module.get());
-#    for (llvm::GlobalVariable &gv : llvmModule->globals()) {
-#      if (!deserializer.processGlobal(&gv))
-#        return {};
-#    }
-#    for (llvm::Function &f : llvmModule->functions()) {
-#      if (failed(deserializer.processFunction(&f)))
-#        return {};
-#    }
-#    return module;
-#  }
- // Deserializes the LLVM bitcode stored in `input` into an MLIR module in the
- // LLVM dialect.
- OwningOpRef<ModuleOp> translateLLVMIRToModule(llvm::SourceMgr &sourceMgr,
-                                               MLIRContext *context) {
-   llvm::SMDiagnostic err;
-   llvm::LLVMContext llvmContext;
-   std::unique_ptr<llvm::Module> llvmModule = llvm::parseIR(
-       *sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), err, llvmContext);
-   if (!llvmModule) {
-     std::string errStr;
-     llvm::raw_string_ostream errStream(errStr);
-     err.print(/*ProgName=*/"", errStream);
-     emitError(UnknownLoc::get(context)) << errStream.str();
-     return {};
-   }
-   return translateLLVMIRToModule(std::move(llvmModule), context);
- }
- namespace mlir {
- void registerFromLLVMIRTranslation() {
-   TranslateToMLIRRegistration fromLLVM(
--      "import-llvm", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) {
-+      "import-llvm", "from llvm to mlir",
-+      [](llvm::SourceMgr &sourceMgr, MLIRContext *context) {
-         return ::translateLLVMIRToModule(sourceMgr, context);
-       });
- }
- } // namespace mlir
-diff --git a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
-index 70f86d2..1ae7b83 100644
---- a/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
-+++ b/mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
-@@ -1,42 +1,42 @@
- //===- ConvertToLLVMIR.cpp - MLIR to LLVM IR conversion -------------------===//
- //
- // 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 implements a translation between the MLIR LLVM dialect and LLVM IR.
- //
- //===----------------------------------------------------------------------===//
- #include "mlir/Dialect/DLTI/DLTI.h"
- #include "mlir/Dialect/Func/IR/FuncOps.h"
- #include "mlir/IR/BuiltinOps.h"
- #include "mlir/Target/LLVMIR/Dialect/All.h"
- #include "mlir/Target/LLVMIR/Export.h"
- #include "mlir/Tools/mlir-translate/Translation.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- using namespace mlir;
- namespace mlir {
- void registerToLLVMIRTranslation() {
-   TranslateFromMLIRRegistration registration(
--      "mlir-to-llvmir",
-+      "mlir-to-llvmir", "translate mlir to llvmir",
-       [](ModuleOp module, raw_ostream &output) {
-         llvm::LLVMContext llvmContext;
-         auto llvmModule = translateModuleToLLVMIR(module, llvmContext);
-         if (!llvmModule)
-           return failure();
-         llvmModule->print(output, nullptr);
-         return success();
-       },
-       [](DialectRegistry &registry) {
-         registry.insert<DLTIDialect, func::FuncDialect>();
-         registerAllToLLVMIRTranslations(registry);
-       });
- }
- } // namespace mlir
-diff --git a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
-index 664b796..d24e578 100644
---- a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
-+++ b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp
-@@ -1,184 +1,184 @@
- //===- TranslateRegistration.cpp - hooks to mlir-translate ----------------===//
- //
- // 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 implements a translation from SPIR-V binary module to MLIR SPIR-V
- // ModuleOp.
- //
- //===----------------------------------------------------------------------===//
- #include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h"
- #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
- #include "mlir/IR/Builders.h"
- #include "mlir/IR/BuiltinOps.h"
- #include "mlir/IR/Dialect.h"
- #include "mlir/IR/Verifier.h"
- #include "mlir/Parser/Parser.h"
- #include "mlir/Support/FileUtilities.h"
- #include "mlir/Target/SPIRV/Deserialization.h"
- #include "mlir/Target/SPIRV/Serialization.h"
- #include "mlir/Tools/mlir-translate/Translation.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Support/MemoryBuffer.h"
- #include "llvm/Support/SMLoc.h"
- #include "llvm/Support/SourceMgr.h"
- #include "llvm/Support/ToolOutputFile.h"
- using namespace mlir;
- //===----------------------------------------------------------------------===//
- // Deserialization registration
- //===----------------------------------------------------------------------===//
- // Deserializes the SPIR-V binary module stored in the file named as
- // `inputFilename` and returns a module containing the SPIR-V module.
- static OwningOpRef<ModuleOp> deserializeModule(const llvm::MemoryBuffer *input,
-                                                MLIRContext *context) {
-   context->loadDialect<spirv::SPIRVDialect>();
-   // Make sure the input stream can be treated as a stream of SPIR-V words
-   auto *start = input->getBufferStart();
-   auto size = input->getBufferSize();
-   if (size % sizeof(uint32_t) != 0) {
-     emitError(UnknownLoc::get(context))
-         << "SPIR-V binary module must contain integral number of 32-bit words";
-     return {};
-   }
-   auto binary = llvm::makeArrayRef(reinterpret_cast<const uint32_t *>(start),
-                                    size / sizeof(uint32_t));
-   OwningOpRef<spirv::ModuleOp> spirvModule =
-       spirv::deserialize(binary, context);
-   if (!spirvModule)
-     return {};
-   OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
-       context, input->getBufferIdentifier(), /*line=*/0, /*column=*/0)));
-   module->getBody()->push_front(spirvModule.release());
-   return module;
- }
- namespace mlir {
- void registerFromSPIRVTranslation() {
-   TranslateToMLIRRegistration fromBinary(
--      "deserialize-spirv",
-+      "deserialize-spirv", "deserializes the SPIR-V module",
-       [](llvm::SourceMgr &sourceMgr, MLIRContext *context) {
-         assert(sourceMgr.getNumBuffers() == 1 && "expected one buffer");
-         return deserializeModule(
-             sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), context);
-       });
- }
- } // namespace mlir
- //===----------------------------------------------------------------------===//
- // Serialization registration
- //===----------------------------------------------------------------------===//
- static LogicalResult serializeModule(ModuleOp module, raw_ostream &output) {
-   if (!module)
-     return failure();
-   SmallVector<uint32_t, 0> binary;
-   SmallVector<spirv::ModuleOp, 1> spirvModules;
-   module.walk([&](spirv::ModuleOp op) { spirvModules.push_back(op); });
-   if (spirvModules.empty())
-     return module.emitError("found no 'spirv.module' op");
-   if (spirvModules.size() != 1)
-     return module.emitError("found more than one 'spirv.module' op");
-   if (failed(spirv::serialize(spirvModules[0], binary)))
-     return failure();
-   output.write(reinterpret_cast<char *>(binary.data()),
-                binary.size() * sizeof(uint32_t));
-   return mlir::success();
- }
- namespace mlir {
- void registerToSPIRVTranslation() {
-   TranslateFromMLIRRegistration toBinary(
--      "serialize-spirv",
-+      "serialize-spirv", "serialize SPIR-V dialect",
-       [](ModuleOp module, raw_ostream &output) {
-         return serializeModule(module, output);
-       },
-       [](DialectRegistry &registry) {
-         registry.insert<spirv::SPIRVDialect>();
-       });
- }
- } // namespace mlir
- //===----------------------------------------------------------------------===//
- // Round-trip registration
- //===----------------------------------------------------------------------===//
- static LogicalResult roundTripModule(ModuleOp srcModule, bool emitDebugInfo,
-                                      raw_ostream &output) {
-   SmallVector<uint32_t, 0> binary;
-   MLIRContext *context = srcModule.getContext();
-   auto spirvModules = srcModule.getOps<spirv::ModuleOp>();
-   if (spirvModules.begin() == spirvModules.end())
-     return srcModule.emitError("found no 'spirv.module' op");
-   if (std::next(spirvModules.begin()) != spirvModules.end())
-     return srcModule.emitError("found more than one 'spirv.module' op");
-   spirv::SerializationOptions options;
-   options.emitDebugInfo = emitDebugInfo;
-   if (failed(spirv::serialize(*spirvModules.begin(), binary, options)))
-     return failure();
-   MLIRContext deserializationContext(context->getDialectRegistry());
-   // TODO: we should only load the required dialects instead of all dialects.
-   deserializationContext.loadAllAvailableDialects();
-   // Then deserialize to get back a SPIR-V module.
-   OwningOpRef<spirv::ModuleOp> spirvModule =
-       spirv::deserialize(binary, &deserializationContext);
-   if (!spirvModule)
-     return failure();
-   // Wrap around in a new MLIR module.
-   OwningOpRef<ModuleOp> dstModule(ModuleOp::create(
-       FileLineColLoc::get(&deserializationContext,
-                           /*filename=*/"", /*line=*/0, /*column=*/0)));
-   dstModule->getBody()->push_front(spirvModule.release());
-   if (failed(verify(*dstModule)))
-     return failure();
-   dstModule->print(output);
-   return mlir::success();
- }
- namespace mlir {
- void registerTestRoundtripSPIRV() {
-   TranslateFromMLIRRegistration roundtrip(
--      "test-spirv-roundtrip",
-+      "test-spirv-roundtrip", "test roundtrip in SPIR-V dialect",
-       [](ModuleOp module, raw_ostream &output) {
-         return roundTripModule(module, /*emitDebugInfo=*/false, output);
-       },
-       [](DialectRegistry &registry) {
-         registry.insert<spirv::SPIRVDialect>();
-       });
- }
- void registerTestRoundtripDebugSPIRV() {
-   TranslateFromMLIRRegistration roundtrip(
--      "test-spirv-roundtrip-debug",
-+      "test-spirv-roundtrip-debug", "test roundtrip debug in SPIR-V",
-       [](ModuleOp module, raw_ostream &output) {
-         return roundTripModule(module, /*emitDebugInfo=*/true, output);
-       },
-       [](DialectRegistry &registry) {
-         registry.insert<spirv::SPIRVDialect>();
-       });
- }
- } // namespace mlir
-diff --git a/mlir/lib/Tools/mlir-translate/Translation.cpp b/mlir/lib/Tools/mlir-translate/Translation.cpp
-index 50b8547..7517ae0 100644
---- a/mlir/lib/Tools/mlir-translate/Translation.cpp
-+++ b/mlir/lib/Tools/mlir-translate/Translation.cpp
-@@ -1,126 +1,140 @@
- //===- Translation.cpp - Translation registry -----------------------------===//
- //
- // 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
- //
- //===----------------------------------------------------------------------===//
- //
- // Definitions of the translation registry.
- //
- //===----------------------------------------------------------------------===//
- #include "mlir/Tools/mlir-translate/Translation.h"
- #include "mlir/IR/AsmState.h"
- #include "mlir/IR/BuiltinOps.h"
- #include "mlir/IR/Dialect.h"
- #include "mlir/IR/Verifier.h"
- #include "mlir/Parser/Parser.h"
- #include "llvm/Support/SourceMgr.h"
- using namespace mlir;
- //===----------------------------------------------------------------------===//
- // Translation Registry
- //===----------------------------------------------------------------------===//
-+struct TranslationBundle {
-+  TranslateFunction translateFunction;
-+  StringRef translateDescription;
-+};
-+
- /// Get the mutable static map between registered file-to-file MLIR translations
--/// and the TranslateFunctions that perform those translations.
--static llvm::StringMap<TranslateFunction> &getTranslationRegistry() {
--  static llvm::StringMap<TranslateFunction> translationRegistry;
--  return translationRegistry;
-+/// and TranslateFunctions with its description that perform those translations.
-+static llvm::StringMap<TranslationBundle> &getTranslationRegistry() {
-+  static llvm::StringMap<TranslationBundle> translationBundle;
-+  return translationBundle;
- }
- /// Register the given translation.
--static void registerTranslation(StringRef name,
-+static void registerTranslation(StringRef name, StringRef description,
-                                 const TranslateFunction &function) {
-   auto &translationRegistry = getTranslationRegistry();
-   if (translationRegistry.find(name) != translationRegistry.end())
-     llvm::report_fatal_error(
-         "Attempting to overwrite an existing <file-to-file> function");
-   assert(function &&
-          "Attempting to register an empty translate <file-to-file> function");
--  translationRegistry[name] = function;
-+  translationRegistry[name].translateFunction = function;
-+  translationRegistry[name].translateDescription = description;
- }
- TranslateRegistration::TranslateRegistration(
--    StringRef name, const TranslateFunction &function) {
--  registerTranslation(name, function);
-+    StringRef name, StringRef description, const TranslateFunction &function) {
-+  registerTranslation(name, description, function);
- }
- //===----------------------------------------------------------------------===//
- // Translation to MLIR
- //===----------------------------------------------------------------------===//
- // Puts `function` into the to-MLIR translation registry unless there is already
- // a function registered for the same name.
- static void registerTranslateToMLIRFunction(
--    StringRef name, const TranslateSourceMgrToMLIRFunction &function) {
-+    StringRef name, StringRef description,
-+    const TranslateSourceMgrToMLIRFunction &function) {
-   auto wrappedFn = [function](llvm::SourceMgr &sourceMgr, raw_ostream &output,
-                               MLIRContext *context) {
-     OwningOpRef<ModuleOp> module = function(sourceMgr, context);
-     if (!module || failed(verify(*module)))
-       return failure();
-     module->print(output);
-     return success();
-   };
--  registerTranslation(name, wrappedFn);
-+  registerTranslation(name, description, wrappedFn);
- }
- TranslateToMLIRRegistration::TranslateToMLIRRegistration(
--    StringRef name, const TranslateSourceMgrToMLIRFunction &function) {
--  registerTranslateToMLIRFunction(name, function);
-+    StringRef name, StringRef description,
-+    const TranslateSourceMgrToMLIRFunction &function) {
-+  registerTranslateToMLIRFunction(name, description, function);
- }
--
- /// Wraps `function` with a lambda that extracts a StringRef from a source
- /// manager and registers the wrapper lambda as a to-MLIR conversion.
- TranslateToMLIRRegistration::TranslateToMLIRRegistration(
--    StringRef name, const TranslateStringRefToMLIRFunction &function) {
-+    StringRef name, StringRef description,
-+    const TranslateStringRefToMLIRFunction &function) {
-   registerTranslateToMLIRFunction(
--      name, [function](llvm::SourceMgr &sourceMgr, MLIRContext *ctx) {
-+      name, description,
-+      [function](llvm::SourceMgr &sourceMgr, MLIRContext *ctx) {
-         const llvm::MemoryBuffer *buffer =
-             sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID());
-         return function(buffer->getBuffer(), ctx);
-       });
- }
- //===----------------------------------------------------------------------===//
- // Translation from MLIR
- //===----------------------------------------------------------------------===//
- TranslateFromMLIRRegistration::TranslateFromMLIRRegistration(
--    StringRef name, const TranslateFromMLIRFunction &function,
-+    StringRef name, StringRef description,
-+    const TranslateFromMLIRFunction &function,
-     const std::function<void(DialectRegistry &)> &dialectRegistration) {
--  registerTranslation(name, [function, dialectRegistration](
--                                llvm::SourceMgr &sourceMgr, raw_ostream &output,
--                                MLIRContext *context) {
--    DialectRegistry registry;
--    dialectRegistration(registry);
--    context->appendDialectRegistry(registry);
--    auto module = parseSourceFile<ModuleOp>(sourceMgr, context);
--    if (!module || failed(verify(*module)))
--      return failure();
--    return function(module.get(), output);
--  });
-+  registerTranslation(name, description,
-+                      [function, dialectRegistration](
-+                          llvm::SourceMgr &sourceMgr, raw_ostream &output,
-+                          MLIRContext *context) {
-+                        DialectRegistry registry;
-+                        dialectRegistration(registry);
-+                        context->appendDialectRegistry(registry);
-+                        auto module =
-+                            parseSourceFile<ModuleOp>(sourceMgr, context);
-+                        if (!module || failed(verify(*module)))
-+                          return failure();
-+                        return function(module.get(), output);
-+                      });
- }
- //===----------------------------------------------------------------------===//
- // Translation Parser
- //===----------------------------------------------------------------------===//
- TranslationParser::TranslationParser(llvm::cl::Option &opt)
-     : llvm::cl::parser<const TranslateFunction *>(opt) {
--  for (const auto &kv : getTranslationRegistry())
--    addLiteralOption(kv.first(), &kv.second, kv.first());
-+  for (const auto &kv : getTranslationRegistry()) {
-+    addLiteralOption(kv.first(), &kv.second.translateFunction,
-+                     kv.second.translateDescription);
-+  }
- }
- void TranslationParser::printOptionInfo(const llvm::cl::Option &o,
-                                         size_t globalWidth) const {
-   TranslationParser *tp = const_cast<TranslationParser *>(this);
-   llvm::array_pod_sort(tp->Values.begin(), tp->Values.end(),
-                        [](const TranslationParser::OptionInfo *lhs,
-                           const TranslationParser::OptionInfo *rhs) {
-                          return lhs->Name.compare(rhs->Name);
-                        });
-   llvm::cl::parser<const TranslateFunction *>::printOptionInfo(o, globalWidth);
- }