brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · c88b328 Raw
239 lines · cpp
1//===- BuiltinDialect.cpp - MLIR Builtin Dialect --------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the Builtin dialect that contains all of the attributes,10// operations, and types that are necessary for the validity of the IR.11//12//===----------------------------------------------------------------------===//13 14#include "mlir/IR/BuiltinDialect.h"15#include "BuiltinDialectBytecode.h"16#include "mlir/IR/Builders.h"17#include "mlir/IR/BuiltinOps.h"18#include "mlir/IR/BuiltinTypes.h"19#include "mlir/IR/DialectResourceBlobManager.h"20#include "mlir/IR/OpImplementation.h"21#include "mlir/IR/TypeRange.h"22 23using namespace mlir;24 25//===----------------------------------------------------------------------===//26// TableGen'erated dialect27//===----------------------------------------------------------------------===//28 29#include "mlir/IR/BuiltinDialect.cpp.inc"30 31//===----------------------------------------------------------------------===//32// BuiltinBlobManagerInterface33//===----------------------------------------------------------------------===//34 35using BuiltinBlobManagerInterface =36    ResourceBlobManagerDialectInterfaceBase<DenseResourceElementsHandle>;37 38//===----------------------------------------------------------------------===//39// BuiltinOpAsmDialectInterface40//===----------------------------------------------------------------------===//41 42namespace {43struct BuiltinOpAsmDialectInterface : public OpAsmDialectInterface {44  BuiltinOpAsmDialectInterface(Dialect *dialect,45                               BuiltinBlobManagerInterface &mgr)46      : OpAsmDialectInterface(dialect), blobManager(mgr) {}47 48  AliasResult getAlias(Attribute attr, raw_ostream &os) const override {49    if (llvm::isa<LocationAttr>(attr)) {50      os << "loc";51      return AliasResult::OverridableAlias;52    }53    if (auto distinct = llvm::dyn_cast<DistinctAttr>(attr))54      if (!llvm::isa<UnitAttr>(distinct.getReferencedAttr())) {55        os << "distinct";56        return AliasResult::OverridableAlias;57      }58    return AliasResult::NoAlias;59  }60 61  AliasResult getAlias(Type type, raw_ostream &os) const final {62    if (auto tupleType = llvm::dyn_cast<TupleType>(type)) {63      if (tupleType.size() > 16) {64        os << "tuple";65        return AliasResult::OverridableAlias;66      }67    }68    return AliasResult::NoAlias;69  }70 71  //===------------------------------------------------------------------===//72  // Resources73  //===------------------------------------------------------------------===//74 75  std::string76  getResourceKey(const AsmDialectResourceHandle &handle) const override {77    return cast<DenseResourceElementsHandle>(handle).getKey().str();78  }79  FailureOr<AsmDialectResourceHandle>80  declareResource(StringRef key) const final {81    return blobManager.insert(key);82  }83  LogicalResult parseResource(AsmParsedResourceEntry &entry) const final {84    FailureOr<AsmResourceBlob> blob = entry.parseAsBlob();85    if (failed(blob))86      return failure();87 88    // Update the blob for this entry.89    blobManager.update(entry.getKey(), std::move(*blob));90    return success();91  }92  void93  buildResources(Operation *op,94                 const SetVector<AsmDialectResourceHandle> &referencedResources,95                 AsmResourceBuilder &provider) const final {96    blobManager.buildResources(provider, referencedResources.getArrayRef());97  }98 99private:100  /// The blob manager for the dialect.101  BuiltinBlobManagerInterface &blobManager;102};103} // namespace104 105void BuiltinDialect::initialize() {106  registerTypes();107  registerAttributes();108  registerLocationAttributes();109  addOperations<110#define GET_OP_LIST111#include "mlir/IR/BuiltinOps.cpp.inc"112      >();113 114  auto &blobInterface = addInterface<BuiltinBlobManagerInterface>();115  addInterface<BuiltinOpAsmDialectInterface>(blobInterface);116  builtin_dialect_detail::addBytecodeInterface(this);117}118 119//===----------------------------------------------------------------------===//120// ModuleOp121//===----------------------------------------------------------------------===//122 123void ModuleOp::build(OpBuilder &builder, OperationState &state,124                     std::optional<StringRef> name) {125  state.addRegion()->emplaceBlock();126  if (name) {127    state.attributes.push_back(builder.getNamedAttr(128        mlir::SymbolTable::getSymbolAttrName(), builder.getStringAttr(*name)));129  }130}131 132/// Construct a module from the given context.133ModuleOp ModuleOp::create(Location loc, std::optional<StringRef> name) {134  OpBuilder builder(loc->getContext());135  return ModuleOp::create(builder, loc, name);136}137 138DataLayoutSpecInterface ModuleOp::getDataLayoutSpec() {139  // Take the first and only (if present) attribute that implements the140  // interface. This needs a linear search, but is called only once per data141  // layout object construction that is used for repeated queries.142  for (NamedAttribute attr : getOperation()->getAttrs())143    if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(attr.getValue()))144      return spec;145  return {};146}147 148TargetSystemSpecInterface ModuleOp::getTargetSystemSpec() {149  // Take the first and only (if present) attribute that implements the150  // interface. This needs a linear search, but is called only once per data151  // layout object construction that is used for repeated queries.152  for (NamedAttribute attr : getOperation()->getAttrs())153    if (auto spec = llvm::dyn_cast<TargetSystemSpecInterface>(attr.getValue()))154      return spec;155  return {};156}157 158LogicalResult ModuleOp::verify() {159  // Check that none of the attributes are non-dialect attributes, except for160  // the symbol related attributes.161  for (auto attr : (*this)->getAttrs()) {162    if (!attr.getName().strref().contains('.') &&163        !llvm::is_contained(164            ArrayRef<StringRef>{mlir::SymbolTable::getSymbolAttrName(),165                                mlir::SymbolTable::getVisibilityAttrName()},166            attr.getName().strref()))167      return emitOpError() << "can only contain attributes with "168                              "dialect-prefixed names, found: '"169                           << attr.getName().getValue() << "'";170  }171 172  // Check that there is at most one data layout spec attribute.173  StringRef layoutSpecAttrName;174  DataLayoutSpecInterface layoutSpec;175  for (const NamedAttribute &na : (*this)->getAttrs()) {176    if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(na.getValue())) {177      if (layoutSpec) {178        InFlightDiagnostic diag =179            emitOpError() << "expects at most one data layout attribute";180        diag.attachNote() << "'" << layoutSpecAttrName181                          << "' is a data layout attribute";182        diag.attachNote() << "'" << na.getName().getValue()183                          << "' is a data layout attribute";184      }185      layoutSpecAttrName = na.getName().strref();186      layoutSpec = spec;187    }188  }189 190  return success();191}192 193//===----------------------------------------------------------------------===//194// UnrealizedConversionCastOp195//===----------------------------------------------------------------------===//196 197LogicalResult198UnrealizedConversionCastOp::fold(FoldAdaptor adaptor,199                                 SmallVectorImpl<OpFoldResult> &foldResults) {200  OperandRange operands = getInputs();201  ResultRange results = getOutputs();202 203  if (operands.getType() == results.getType()) {204    foldResults.append(operands.begin(), operands.end());205    return success();206  }207 208  if (operands.empty())209    return failure();210 211  // Check that the input is a cast with results that all feed into this212  // operation, and operand types that directly match the result types of this213  // operation.214  Value firstInput = operands.front();215  auto inputOp = firstInput.getDefiningOp<UnrealizedConversionCastOp>();216  if (!inputOp || inputOp.getResults() != operands ||217      inputOp.getOperandTypes() != results.getTypes())218    return failure();219 220  // If everything matches up, we can fold the passthrough.221  foldResults.append(inputOp->operand_begin(), inputOp->operand_end());222  return success();223}224 225LogicalResult UnrealizedConversionCastOp::verify() {226  // TODO: The verifier of external models is not called. This op verifier can227  // be removed when that is fixed.228  if (getNumResults() == 0)229    return emitOpError() << "expected at least one result for cast operation";230  return success();231}232 233//===----------------------------------------------------------------------===//234// TableGen'd op method definitions235//===----------------------------------------------------------------------===//236 237#define GET_OP_CLASSES238#include "mlir/IR/BuiltinOps.cpp.inc"239