github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/mlir/lib/IR/Dialect.cpp (about)

     1  //===- Dialect.cpp - Dialect implementation -------------------------------===//
     2  //
     3  // Copyright 2019 The MLIR Authors.
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //   http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  // =============================================================================
    17  
    18  #include "mlir/IR/Dialect.h"
    19  #include "mlir/IR/Diagnostics.h"
    20  #include "mlir/IR/DialectHooks.h"
    21  #include "mlir/IR/DialectInterface.h"
    22  #include "mlir/IR/MLIRContext.h"
    23  #include "mlir/IR/Operation.h"
    24  #include "llvm/ADT/Twine.h"
    25  #include "llvm/Support/ManagedStatic.h"
    26  #include "llvm/Support/Regex.h"
    27  
    28  using namespace mlir;
    29  using namespace detail;
    30  
    31  //===----------------------------------------------------------------------===//
    32  // Dialect Registration
    33  //===----------------------------------------------------------------------===//
    34  
    35  // Registry for all dialect allocation functions.
    36  static llvm::ManagedStatic<SmallVector<DialectAllocatorFunction, 8>>
    37      dialectRegistry;
    38  
    39  // Registry for functions that set dialect hooks.
    40  static llvm::ManagedStatic<SmallVector<DialectHooksSetter, 8>>
    41      dialectHooksRegistry;
    42  
    43  /// Registers a specific dialect creation function with the system, typically
    44  /// used through the DialectRegistration template.
    45  void mlir::registerDialectAllocator(const DialectAllocatorFunction &function) {
    46    assert(function &&
    47           "Attempting to register an empty dialect initialize function");
    48    dialectRegistry->push_back(function);
    49  }
    50  
    51  /// Registers a function to set specific hooks for a specific dialect, typically
    52  /// used through the DialectHooksRegistreation template.
    53  void mlir::registerDialectHooksSetter(const DialectHooksSetter &function) {
    54    assert(
    55        function &&
    56        "Attempting to register an empty dialect hooks initialization function");
    57  
    58    dialectHooksRegistry->push_back(function);
    59  }
    60  
    61  /// Registers all dialects and their const folding hooks with the specified
    62  /// MLIRContext.
    63  void mlir::registerAllDialects(MLIRContext *context) {
    64    for (const auto &fn : *dialectRegistry)
    65      fn(context);
    66    for (const auto &fn : *dialectHooksRegistry) {
    67      fn(context);
    68    }
    69  }
    70  
    71  //===----------------------------------------------------------------------===//
    72  // Dialect
    73  //===----------------------------------------------------------------------===//
    74  
    75  Dialect::Dialect(StringRef name, MLIRContext *context)
    76      : name(name), context(context) {
    77    assert(isValidNamespace(name) && "invalid dialect namespace");
    78    registerDialect(context);
    79  }
    80  
    81  Dialect::~Dialect() {}
    82  
    83  /// Verify an attribute from this dialect on the argument at 'argIndex' for
    84  /// the region at 'regionIndex' on the given operation. Returns failure if
    85  /// the verification failed, success otherwise. This hook may optionally be
    86  /// invoked from any operation containing a region.
    87  LogicalResult Dialect::verifyRegionArgAttribute(Operation *, unsigned, unsigned,
    88                                                  NamedAttribute) {
    89    return success();
    90  }
    91  
    92  /// Parse an attribute registered to this dialect.
    93  Attribute Dialect::parseAttribute(StringRef attrData, Type type,
    94                                    Location loc) const {
    95    emitError(loc) << "dialect '" << getNamespace()
    96                   << "' provides no attribute parsing hook";
    97    return Attribute();
    98  }
    99  
   100  /// Parse a type registered to this dialect.
   101  Type Dialect::parseType(StringRef tyData, Location loc) const {
   102    // If this dialect allows unknown types, then represent this with OpaqueType.
   103    if (allowsUnknownTypes()) {
   104      auto ns = Identifier::get(getNamespace(), getContext());
   105      return OpaqueType::get(ns, tyData, getContext());
   106    }
   107  
   108    emitError(loc) << "dialect '" << getNamespace()
   109                   << "' provides no type parsing hook";
   110    return Type();
   111  }
   112  
   113  /// Utility function that returns if the given string is a valid dialect
   114  /// namespace.
   115  bool Dialect::isValidNamespace(StringRef str) {
   116    if (str.empty())
   117      return true;
   118    llvm::Regex dialectNameRegex("^[a-zA-Z_][a-zA-Z_0-9\\$]*$");
   119    return dialectNameRegex.match(str);
   120  }
   121  
   122  /// Register a set of dialect interfaces with this dialect instance.
   123  void Dialect::addInterface(std::unique_ptr<DialectInterface> interface) {
   124    auto it = registeredInterfaces.try_emplace(interface->getID(),
   125                                               std::move(interface));
   126    (void)it;
   127    assert(it.second && "interface kind has already been registered");
   128  }
   129  
   130  //===----------------------------------------------------------------------===//
   131  // Dialect Interface
   132  //===----------------------------------------------------------------------===//
   133  
   134  DialectInterface::~DialectInterface() {}
   135  
   136  DialectInterfaceCollectionBase::DialectInterfaceCollectionBase(
   137      MLIRContext *ctx, ClassID *interfaceKind) {
   138    for (auto *dialect : ctx->getRegisteredDialects()) {
   139      if (auto *interface = dialect->getRegisteredInterface(interfaceKind)) {
   140        interfaces.insert(interface);
   141        orderedInterfaces.push_back(interface);
   142      }
   143    }
   144  }
   145  
   146  DialectInterfaceCollectionBase::~DialectInterfaceCollectionBase() {}
   147  
   148  /// Get the interface for the dialect of given operation, or null if one
   149  /// is not registered.
   150  const DialectInterface *
   151  DialectInterfaceCollectionBase::getInterfaceFor(Operation *op) const {
   152    return getInterfaceFor(op->getDialect());
   153  }